From 13f7980ca3666a88f29728f13ab8a9a8253fe316 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Wed, 18 Dec 2024 12:59:05 -0500 Subject: [PATCH 01/10] * Adds an 'Import Latest Test Plan Versions' button to the Data Management page for an admin user * Allows navigation to the /settings page for the admin which will now also include the button mentioned above. It will also display the date of the latest imported test plan version --- client/components/App/App.jsx | 4 +- client/components/DataManagement/index.jsx | 304 ++++++++++-------- .../components/UserSettings/AdminSettings.jsx | 79 +++++ .../UserSettings/TesterSettings.jsx | 106 ++++++ .../components/UserSettings/UserSettings.jsx | 143 -------- client/components/UserSettings/index.js | 87 ++++- client/components/UserSettings/queries.js | 11 +- .../common/BasicThemedModal/index.jsx | 20 +- client/hooks/useThemedModal.js | 7 +- client/tests/e2e/snapshots/saved/_.html | 8 + client/tests/e2e/snapshots/saved/_404.html | 8 + .../snapshots/saved/_account_settings.html | 62 +--- .../snapshots/saved/_candidate-review.html | 8 + .../saved/_candidate-test-plan_24_1.html | 8 + .../e2e/snapshots/saved/_data-management.html | 31 +- .../saved/_data-management_meter.html | 8 + .../saved/_report_67_targets_20.html | 8 + .../tests/e2e/snapshots/saved/_reports.html | 8 + client/tests/e2e/snapshots/saved/_run_2.html | 8 + .../snapshots/saved/_signup-instructions.html | 8 + .../snapshots/saved/_test-plan-report_1.html | 8 + .../e2e/snapshots/saved/_test-queue.html | 8 + .../saved/_test-queue_2_conflicts.html | 8 + .../e2e/snapshots/saved/_test-review_8.html | 8 + server/graphql-schema.js | 4 + server/resolvers/index.js | 2 + .../latestTestPlanVersionResolver.js | 24 ++ server/util/constants.js | 2 +- 28 files changed, 642 insertions(+), 348 deletions(-) create mode 100644 client/components/UserSettings/AdminSettings.jsx create mode 100644 client/components/UserSettings/TesterSettings.jsx delete mode 100644 client/components/UserSettings/UserSettings.jsx create mode 100644 server/resolvers/latestTestPlanVersionResolver.js diff --git a/client/components/App/App.jsx b/client/components/App/App.jsx index 143a245a3..286460186 100644 --- a/client/components/App/App.jsx +++ b/client/components/App/App.jsx @@ -19,7 +19,7 @@ const App = () => { const [isNavbarExpanded, setIsNavbarExpanded] = useState(false); const auth = evaluateAuth(data && data.me ? data.me : {}); - const { username, isSignedIn, isAdmin, isVendor } = auth; + const { username, isSignedIn, isAdmin, isVendor, isTester } = auth; const signOut = async () => { await fetch('/api/auth/signout', { method: 'POST' }); @@ -104,7 +104,7 @@ const App = () => { )} {isSignedIn && ( <> - {!isVendor && ( + {(isAdmin || isTester) && (
  • { + const { triggerLoad, loadingMessage } = useTriggerLoad(); const { loading, data, error, refetch } = useQuery( DATA_MANAGEMENT_PAGE_QUERY, { fetchPolicy: 'cache-and-network' } @@ -71,6 +73,25 @@ const DataManagement = () => { TABLE_SORT_ORDERS.DESC ); + const handleImportTests = async () => { + await triggerLoad(async () => { + try { + const response = await fetch('/api/test/import', { method: 'POST' }); + if (!response.ok) { + throw new Error( + `Failed to import the latest Test Plan Versions: ${response.status}` + ); + } + + // Success + await refetch(); + } catch (e) { + // Failed + console.error(e); + } + }, 'Importing latest Test Plan Versions'); + }; + if (error) { return ( { const emptyTestPlans = !testPlans.length; return ( - - - Data Management | ARIA-AT - -

    Data Management

    - - {emptyTestPlans && ( -

    - There are no Test Plans available -

    - )} - - {emptyTestPlans && isAdmin && ( - - Add a Test Plan to the Queue - - )} - - {isAdmin ? ( - <> -

    Introduction

    -

    - This page provides a view of the latest test plan version - information, and where they currently are in the{' '} - - ARIA-AT Community Group’s review process - - .
    - Use this page to manage Test Plans in the Test Queue and their - phases. -

    - - - - ) : ( - <> -

    Introduction

    -

    - This page provides a view of the latest test plan version - information, and where they currently are in the{' '} - - ARIA-AT Community Group’s review process - - . -

    - - )} - -

    Test Plans Status Summary

    - - - - - - updateSort({ - key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.NAME, - direction - }) - } - /> - - updateSort({ - key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.ATS, - direction - }) - } - /> - - updateSort({ - key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.PHASE, - direction - }) - } - initialSortDirection={TABLE_SORT_ORDERS.DESC} + + + + Data Management | ARIA-AT + +

    Data Management

    + + {emptyTestPlans && ( +

    + There are no Test Plans available +

    + )} + + {emptyTestPlans && isAdmin && ( + + Add a Test Plan to the Queue + + )} + + {isAdmin ? ( + <> +

    Introduction

    +

    + This page provides a view of the latest test plan version + information, and where they currently are in the{' '} + + ARIA-AT Community Group’s review process + + .
    + Use this page to manage Test Plans in the Test Queue and their + phases. +

    + + -
    - - - - - - - {sortedTestPlans.map((testPlan, index) => { - return ( - - testPlanVersion.testPlan.directory === testPlan.directory - )} - tableRowIndex={index} - setTestPlanVersions={setTestPlanVersions} + + ) : ( + <> +

    Introduction

    +

    + This page provides a view of the latest test plan version + information, and where they currently are in the{' '} + + ARIA-AT Community Group’s review process + + . +

    + + )} + +

    Test Plans Status Summary

    + + + {isAdmin && ( + + )} + +
    R&D VersionDraft ReviewCandidate ReviewRecommended Version
    + + + + updateSort({ + key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.NAME, + direction + }) + } + /> + + updateSort({ + key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.ATS, + direction + }) + } + /> + + updateSort({ + key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.PHASE, + direction + }) + } + initialSortDirection={TABLE_SORT_ORDERS.DESC} /> - ); - })} - -
    -
    + R&D Version + Draft Review + Candidate Review + Recommended Version + + + + {sortedTestPlans.map((testPlan, index) => { + return ( + + testPlanVersion.testPlan.directory === testPlan.directory + )} + tableRowIndex={index} + setTestPlanVersions={setTestPlanVersions} + /> + ); + })} + + + + ); }; diff --git a/client/components/UserSettings/AdminSettings.jsx b/client/components/UserSettings/AdminSettings.jsx new file mode 100644 index 000000000..9e7bbacdd --- /dev/null +++ b/client/components/UserSettings/AdminSettings.jsx @@ -0,0 +1,79 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Button } from 'react-bootstrap'; +import { LoadingStatus, useTriggerLoad } from '../common/LoadingStatus'; +import { useThemedModal, THEMES } from '../../hooks/useThemedModal'; +import { dates } from 'shared'; + +const AdminSettings = ({ latestTestPlanVersion, refetch }) => { + const { triggerLoad, loadingMessage } = useTriggerLoad(); + const { + themedModal, + showThemedModal, + setShowThemedModal, + setThemedModalTitle, + setThemedModalContent, + setThemedModalType + } = useThemedModal({ + type: THEMES.SUCCESS, + title: 'Success!' + }); + + const handleImportTests = async () => { + await triggerLoad(async () => { + try { + const response = await fetch('/api/test/import', { method: 'POST' }); + if (!response.ok) { + throw new Error( + `Failed to import the latest Test Plan Versions: ${response.status}` + ); + } + + // Success + setThemedModalType(THEMES.SUCCESS); + setThemedModalTitle('Success!'); + setThemedModalContent( + <>The latest Test Plan Versions have been imported. + ); + setShowThemedModal(true); + await refetch(); + } catch (e) { + // Failed, show themed message + setThemedModalType(THEMES.DANGER); + setThemedModalTitle('Error!'); + setThemedModalContent(<>{e.message}); + setShowThemedModal(true); + } + }, 'Importing latest Test Plan Versions'); + }; + + return ( + +
    +

    Actions

    +

    Use the following actions below to perform a certain function:

    + +

    + Date of latest test plan version:{' '} + {dates.convertDateToString( + latestTestPlanVersion?.updatedAt, + 'MMMM D, YYYY HH:mm z' + )} +

    +
    + {showThemedModal && themedModal} +
    + ); +}; + +AdminSettings.propTypes = { + latestTestPlanVersion: PropTypes.shape({ + id: PropTypes.string.isRequired, + updatedAt: PropTypes.string.isRequired + }), + refetch: PropTypes.func +}; + +export default AdminSettings; diff --git a/client/components/UserSettings/TesterSettings.jsx b/client/components/UserSettings/TesterSettings.jsx new file mode 100644 index 000000000..c88695fe2 --- /dev/null +++ b/client/components/UserSettings/TesterSettings.jsx @@ -0,0 +1,106 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; +import { Button, Form } from 'react-bootstrap'; +import { useMutation } from '@apollo/client'; +import { TESTER_SETTINGS_QUERY, UPDATE_ME_MUTATION } from './queries'; +import { AtPropType } from '../common/proptypes'; + +const TesterSettings = ({ ats, meAts }) => { + const [updateMe] = useMutation(UPDATE_ME_MUTATION, { + refetchQueries: [{ query: TESTER_SETTINGS_QUERY }] + }); + + const [checkedAts, setCheckedAts] = useState([]); + + if (!ats || !meAts || !checkedAts) return null; + + useEffect(() => { + if (!meAts) return; + setCheckedAts(meAts.map(at => at.id)); + }, [meAts]); + + const handleCheckedAt = useCallback( + event => { + const atId = event.target.id; + const isChecked = checkedAts.includes(atId); + if (isChecked) { + setCheckedAts(checkedAts.filter(item => item !== atId)); + } else { + setCheckedAts([...checkedAts, atId]); + } + }, + [checkedAts] + ); + + const handleSave = useCallback( + event => { + event.preventDefault(); + updateMe({ variables: { input: { atIds: checkedAts } } }); + }, + [checkedAts] + ); + + const savedAts = meAts.map(at => at.id); + + return ( +
    +

    Assistive Technology Settings

    +
    + {savedAts.length > 0 ? ( +
    +

    + You can currently test the following assistive technologies: +

    +
      + {ats + .filter(({ id: atId }) => savedAts.includes(atId)) + .map(at => ( +
    • + {at.name} +
    • + ))} +
    +
    + ) : ( +

    + You have not yet selected any assistive technologies. +

    + )} +
    +

    + Update the assistive technologies you can test by selecting from the + options below: +

    +
    +

    Assistive Technologies

    + + {ats?.map(at => { + return ( + atId === at.id)} + /> + ); + })} + + +
    +
    + ); +}; + +TesterSettings.propTypes = { + ats: PropTypes.arrayOf(AtPropType), + meAts: PropTypes.arrayOf(AtPropType) +}; + +export default TesterSettings; diff --git a/client/components/UserSettings/UserSettings.jsx b/client/components/UserSettings/UserSettings.jsx deleted file mode 100644 index 958d27f79..000000000 --- a/client/components/UserSettings/UserSettings.jsx +++ /dev/null @@ -1,143 +0,0 @@ -import React, { useState, useCallback, useEffect } from 'react'; -import { Helmet } from 'react-helmet'; -import { Button, Container, Form } from 'react-bootstrap'; -import { useMutation, useQuery } from '@apollo/client'; -import PageStatus from '../common/PageStatus'; -import { CURRENT_SETTINGS_QUERY, UPDATE_ME_MUTATION } from './queries'; - -const UserSettings = () => { - const { loading, data, error } = useQuery(CURRENT_SETTINGS_QUERY); - - const [updateMe] = useMutation(UPDATE_ME_MUTATION, { - refetchQueries: [{ query: CURRENT_SETTINGS_QUERY }] - }); - - const [checkedAts, setCheckedAts] = useState(undefined); - - const handleCheckedAt = useCallback( - event => { - const atId = event.target.id; - const isChecked = checkedAts.includes(atId); - if (isChecked) { - setCheckedAts(checkedAts.filter(item => item !== atId)); - } else { - setCheckedAts([...checkedAts, atId]); - } - }, - [checkedAts] - ); - - const handleSave = useCallback( - event => { - event.preventDefault(); - updateMe({ variables: { input: { atIds: checkedAts } } }); - }, - [checkedAts] - ); - - useEffect(() => { - if (!data) return; - setCheckedAts(data.me.ats.map(at => at.id)); - }, [data]); - - if (error) { - return ( - - ); - } - - if (loading) { - return ( - - ); - } - - if (!data || !checkedAts) return null; - - const { - ats, - me: { username, ats: userAtsData } - } = data; - const savedAts = userAtsData.map(at => at.id); - - return ( - - - - Settings | ARIA-AT - -

    Settings

    -
    -

    User Details

    -

    - - {username} - -

    -

    Assistive Technology Settings

    -
    - {savedAts.length > 0 ? ( -
    -

    - You can currently test the following assistive technologies: -

    -
      - {ats - .filter(({ id: atId }) => savedAts.includes(atId)) - .map(at => ( -
    • - {at.name} -
    • - ))} -
    -
    - ) : ( -

    - You have not yet selected any assistive technologies. -

    - )} -
    -

    - Update the assistive technologies you can test by selecting from the - options below: -

    -
    -

    Assistive Technologies

    - - {ats && - ats.map(at => { - return ( - atId === at.id)} - /> - ); - })} - - -
    -
    -
    -
    - ); -}; - -export default UserSettings; diff --git a/client/components/UserSettings/index.js b/client/components/UserSettings/index.js index 48df754fd..f040be42d 100644 --- a/client/components/UserSettings/index.js +++ b/client/components/UserSettings/index.js @@ -1,3 +1,88 @@ -import UserSettings from './UserSettings'; +import React from 'react'; +import { Helmet } from 'react-helmet'; +import { Container } from 'react-bootstrap'; +import { useQuery } from '@apollo/client'; +import PageStatus from '../common/PageStatus'; +import TesterSettings from './TesterSettings'; +import AdminSettings from './AdminSettings'; +import { ME_QUERY } from '../App/queries'; +import { TESTER_SETTINGS_QUERY, ADMIN_SETTINGS_QUERY } from './queries'; +import { evaluateAuth } from '../../utils/evaluateAuth'; + +const UserSettings = () => { + const { loading, data, error } = useQuery(ME_QUERY); + + const auth = evaluateAuth(data?.me ? data?.me : {}); + const { username, isAdmin, isVendor, isTester } = auth; + + const { + data: testerQueryData, + loading: testerQueryLoading, + error: testerQueryError + } = useQuery(TESTER_SETTINGS_QUERY, { + skip: isAdmin || isVendor // no need to query if admin or vendor + }); + + const { + data: adminQueryData, + loading: adminQueryLoading, + error: adminQueryError, + refetch: adminQueryRefetch + } = useQuery(ADMIN_SETTINGS_QUERY, { + skip: !isAdmin // no need to query if not admin + }); + + if (error || testerQueryError || adminQueryError) { + return ( + + ); + } + + if (loading || testerQueryLoading || adminQueryLoading) { + return ( + + ); + } + + return ( + + + + Settings | ARIA-AT + +

    Settings

    +
    +

    User Details

    +

    + + {username} + +

    +
    + {!isAdmin && isTester && !isVendor && ( + + )} + {isAdmin && ( + + )} +
    +
    + ); +}; export default UserSettings; diff --git a/client/components/UserSettings/queries.js b/client/components/UserSettings/queries.js index 016588602..7122f2b85 100644 --- a/client/components/UserSettings/queries.js +++ b/client/components/UserSettings/queries.js @@ -1,7 +1,7 @@ import { gql } from '@apollo/client'; import { AT_FIELDS, ME_FIELDS } from '@components/common/fragments'; -export const CURRENT_SETTINGS_QUERY = gql` +export const TESTER_SETTINGS_QUERY = gql` ${AT_FIELDS} ${ME_FIELDS} query CurrentSettings { @@ -17,6 +17,15 @@ export const CURRENT_SETTINGS_QUERY = gql` } `; +export const ADMIN_SETTINGS_QUERY = gql` + query AdminSettings { + latestTestPlanVersion { + id + updatedAt + } + } +`; + export const UPDATE_ME_MUTATION = gql` ${AT_FIELDS} mutation UpdateMe($input: UserInput) { diff --git a/client/components/common/BasicThemedModal/index.jsx b/client/components/common/BasicThemedModal/index.jsx index 5c53c5edb..e542d770a 100644 --- a/client/components/common/BasicThemedModal/index.jsx +++ b/client/components/common/BasicThemedModal/index.jsx @@ -25,8 +25,14 @@ const ColorStrip = styled.div` width: 100%; height: 10px; ${props => props.hideHeadline && `display: none;`} - background-color: ${({ theme }) => - theme === 'danger' ? '#ce1b4c' : '#fab700'}; + background-color: ${ + ({ theme }) => + theme === 'danger' + ? '#ce1b4c' + : theme === 'warning' + ? '#fab700' + : '#2ba51c' // success + }; border-top-left-radius: calc(0.3rem - 1px); border-top-right-radius: calc(0.3rem - 1px); @@ -36,7 +42,7 @@ const BasicThemedModal = ({ show = false, centered = false, animation = true, - theme = 'warning', // warning, danger + theme = 'warning', // warning, danger, success dialogClassName = '', title = null, content = null, @@ -80,7 +86,13 @@ const BasicThemedModal = ({ {title} diff --git a/client/hooks/useThemedModal.js b/client/hooks/useThemedModal.js index a4bca0901..eb6bcc5cb 100644 --- a/client/hooks/useThemedModal.js +++ b/client/hooks/useThemedModal.js @@ -2,15 +2,16 @@ import React, { useState, useRef, useEffect } from 'react'; import BasicThemedModal from '@components/common/BasicThemedModal'; const THEMES = { + SUCCESS: 'success', WARNING: 'warning', DANGER: 'danger' }; -function useThemedModal({ show, type, title, content }) { +function useThemedModal({ show, type = THEMES.WARNING, title, content }) { const focusElementRef = useRef(); const [showThemedModal, setShowThemedModal] = useState(false); - const [themedModalType, setThemedModalType] = useState(THEMES.WARNING); + const [themedModalType, setThemedModalType] = useState(type); const [themedModalTitle, setThemedModalTitle] = useState(''); const [themedModalContent, setThemedModalContent] = useState(<>); const [themedModalActions, setThemedModalActions] = useState(null); @@ -26,7 +27,7 @@ function useThemedModal({ show, type, title, content }) { const hideThemedModal = () => { setShowThemedModal(false); - setThemedModalType(THEMES.WARNING); + setThemedModalType(type); setThemedModalTitle(''); setThemedModalContent(<>); setThemedModalActions(null); diff --git a/client/tests/e2e/snapshots/saved/_.html b/client/tests/e2e/snapshots/saved/_.html index 1b0fdcadb..58b219697 100644 --- a/client/tests/e2e/snapshots/saved/_.html +++ b/client/tests/e2e/snapshots/saved/_.html @@ -50,6 +50,14 @@ >Candidate Review
  • +
  • + Settings +
  • Candidate Review
  • +
  • + Settings +
  • Candidate Review
  • +
  • + Settings +
  • User Details >joe-the-admin

    -

    Assistive Technology Settings

    -
    -

    - You have not yet selected any assistive technologies. -

    -
    + +
    +

    Actions

    +

    + Use the following actions below to perform a certain function: +

    +

    - Update the assistive technologies you can test by selecting from - the options below: + Date of latest test plan version: December 17, 2024 03:04 UTC

    -
    -

    Assistive Technologies

    -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    diff --git a/client/tests/e2e/snapshots/saved/_candidate-review.html b/client/tests/e2e/snapshots/saved/_candidate-review.html index 068c908d6..57a4bb59f 100644 --- a/client/tests/e2e/snapshots/saved/_candidate-review.html +++ b/client/tests/e2e/snapshots/saved/_candidate-review.html @@ -47,6 +47,14 @@ >Candidate Review
  • +
  • + Settings +
  • Candidate Review
  • +
  • + Settings +
  • Candidate Review
  • +
  • + Settings +
  • -

    - +

    @@ -410,6 +418,9 @@

    Test Plans Status Summary

  • + Test Plans Status Summary
    R&D -

    Complete Nov 20, 2024

    +

    Complete Dec 17, 2024

    + + + updateSort({ + key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.NAME, + direction + }) + } /> - - ) : ( - <> -

    Introduction

    -

    - This page provides a view of the latest test plan version - information, and where they currently are in the{' '} - - ARIA-AT Community Group’s review process - - . -

    - - )} - -

    Test Plans Status Summary

    - - - {isAdmin && ( - - )} - -
    @@ -2067,7 +2078,7 @@

    Test Plans Status Summary

    V24.11.20V24.12.17
    R&D -

    Complete Nov 20, 2024

    +

    Complete Dec 17, 2024

    @@ -2122,7 +2133,7 @@

    Test Plans Status Summary

    V24.11.20V24.12.17
    R&D -

    Complete Aug 23, 2023

    +

    Complete Dec 12, 2024

    @@ -2363,7 +2374,7 @@

    Test Plans Status Summary

    V23.08.23V24.12.12
    - - - - updateSort({ - key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.NAME, - direction - }) - } - /> - - updateSort({ - key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.ATS, - direction - }) - } - /> - - updateSort({ - key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.PHASE, - direction - }) - } - initialSortDirection={TABLE_SORT_ORDERS.DESC} + + updateSort({ + key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.ATS, + direction + }) + } + /> + + updateSort({ + key: DATA_MANAGEMENT_TABLE_SORT_OPTIONS.PHASE, + direction + }) + } + initialSortDirection={TABLE_SORT_ORDERS.DESC} + /> + + + + + + + + {sortedTestPlans.map((testPlan, index) => { + return ( + + testPlanVersion.testPlan.directory === testPlan.directory + )} + tableRowIndex={index} + setTestPlanVersions={setTestPlanVersions} /> - - - - - - - - {sortedTestPlans.map((testPlan, index) => { - return ( - - testPlanVersion.testPlan.directory === testPlan.directory - )} - tableRowIndex={index} - setTestPlanVersions={setTestPlanVersions} - /> - ); - })} - -
    R&D VersionDraft ReviewCandidate ReviewRecommended Version
    R&D VersionDraft ReviewCandidate ReviewRecommended Version
    - - + ); + })} + + + ); }; diff --git a/client/tests/e2e/snapshots/saved/_data-management.html b/client/tests/e2e/snapshots/saved/_data-management.html index 9cd459857..3bd396646 100644 --- a/client/tests/e2e/snapshots/saved/_data-management.html +++ b/client/tests/e2e/snapshots/saved/_data-management.html @@ -418,9 +418,6 @@

    Test Plans Status Summary

    - Date: Thu, 23 Jan 2025 10:43:30 -0500 Subject: [PATCH 04/10] Remove superfluous text on settings page for admin actions --- client/components/UserSettings/AdminSettings.jsx | 3 +-- client/tests/e2e/snapshots/saved/_account_settings.html | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/client/components/UserSettings/AdminSettings.jsx b/client/components/UserSettings/AdminSettings.jsx index 9e7bbacdd..2d485de8d 100644 --- a/client/components/UserSettings/AdminSettings.jsx +++ b/client/components/UserSettings/AdminSettings.jsx @@ -50,8 +50,7 @@ const AdminSettings = ({ latestTestPlanVersion, refetch }) => { return (
    -

    Actions

    -

    Use the following actions below to perform a certain function:

    +

    Admin Actions

    diff --git a/client/tests/e2e/snapshots/saved/_account_settings.html b/client/tests/e2e/snapshots/saved/_account_settings.html index f9c0ac05e..a63ada829 100644 --- a/client/tests/e2e/snapshots/saved/_account_settings.html +++ b/client/tests/e2e/snapshots/saved/_account_settings.html @@ -95,10 +95,7 @@

    User Details

    -

    Actions

    -

    - Use the following actions below to perform a certain function: -

    +

    Admin Actions

    From edcc45acff243264eb86c5394e6bc3e84accc36c Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Thu, 23 Jan 2025 10:44:12 -0500 Subject: [PATCH 05/10] Remove unnecessary newline --- client/components/DataManagement/index.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/client/components/DataManagement/index.jsx b/client/components/DataManagement/index.jsx index 4acdc8ff2..fcc1e686f 100644 --- a/client/components/DataManagement/index.jsx +++ b/client/components/DataManagement/index.jsx @@ -158,7 +158,6 @@ const DataManagement = () => { activeFilter={filter} onFilterChange={setFilter} /> -
    Date: Thu, 23 Jan 2025 10:45:50 -0500 Subject: [PATCH 06/10] Revert change to server/util/constants.js --- server/util/constants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/util/constants.js b/server/util/constants.js index 27c126e41..a058e91db 100644 --- a/server/util/constants.js +++ b/server/util/constants.js @@ -6,7 +6,7 @@ const AT_VERSIONS_SUPPORTED_BY_COLLECTION_JOBS = { // https://github.com/bocoup/aria-at-gh-actions-helper/blob/main/.github/workflows/voiceover-test.yml#L39 'VoiceOver for macOS': ['13.0', '14.0'], // These are tracked with the https://github.com/bocoup/aria-at-automation-nvda-builds/releases - NVDA: ['2024.1', '2023.3.3', '2023.3'] + NVDA: ['2024.4.1', '2024.1', '2023.3.3', '2023.3'] }; const VENDOR_NAME_TO_AT_MAPPING = { From c19a17a557153a1cd1b78cf1fa1e2697832bca07 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Thu, 23 Jan 2025 11:03:10 -0500 Subject: [PATCH 07/10] Reusable functions for the theme color values --- .../common/BasicThemedModal/index.jsx | 34 ++++++++----------- client/hooks/useThemedModal.js | 20 ++++++++++- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/client/components/common/BasicThemedModal/index.jsx b/client/components/common/BasicThemedModal/index.jsx index e542d770a..4dbf8b1f2 100644 --- a/client/components/common/BasicThemedModal/index.jsx +++ b/client/components/common/BasicThemedModal/index.jsx @@ -2,9 +2,13 @@ import React, { useEffect, useMemo, useRef } from 'react'; import PropTypes from 'prop-types'; import { Button, Modal } from 'react-bootstrap'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; +import { + faCheckCircle, + faExclamationTriangle +} from '@fortawesome/free-solid-svg-icons'; import styled from '@emotion/styled'; import { uniqueId } from 'lodash'; +import { THEMES, THEME_COLOR } from '@client/hooks/useThemedModal'; import { ActionButtonPropType } from '../proptypes'; const ModalTitleStyle = styled.h1` @@ -25,15 +29,7 @@ const ColorStrip = styled.div` width: 100%; height: 10px; ${props => props.hideHeadline && `display: none;`} - background-color: ${ - ({ theme }) => - theme === 'danger' - ? '#ce1b4c' - : theme === 'warning' - ? '#fab700' - : '#2ba51c' // success - }; - + background-color: ${({ theme }) => THEME_COLOR(theme)}; border-top-left-radius: calc(0.3rem - 1px); border-top-right-radius: calc(0.3rem - 1px); `; @@ -42,7 +38,7 @@ const BasicThemedModal = ({ show = false, centered = false, animation = true, - theme = 'warning', // warning, danger, success + theme = THEMES.WARNING, // warning, danger, success dialogClassName = '', title = null, content = null, @@ -84,15 +80,13 @@ const BasicThemedModal = ({ > {title} @@ -115,7 +109,7 @@ const BasicThemedModal = ({ {actionButtons.map(({ action, text }) => (

    - Date of latest test plan version: December 17, 2024 03:04 UTC + Date of latest test plan version: January 23, 2025 20:56 UTC

    From 91e765cf09d961a823d95737bc7b75269bb26d74 Mon Sep 17 00:00:00 2001 From: Howard Edwards Date: Tue, 28 Jan 2025 09:45:40 -0500 Subject: [PATCH 10/10] Expand UserSettings.e2e.test.js --- client/tests/e2e/UserSettings.e2e.test.js | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/client/tests/e2e/UserSettings.e2e.test.js b/client/tests/e2e/UserSettings.e2e.test.js index f796b7f4a..73bff00c7 100644 --- a/client/tests/e2e/UserSettings.e2e.test.js +++ b/client/tests/e2e/UserSettings.e2e.test.js @@ -43,6 +43,18 @@ describe('User Settings common traits', () => { }); }); + it("renders admin's user details and assistive technology sections", async () => { + await getPage({ role: 'admin', url: '/account/settings' }, async page => { + await page.waitForSelector('h2 ::-p-text(User Details)'); + await page.waitForSelector('h2 ::-p-text(Admin Actions)'); + + const admin = 'joe-the-admin'; + await page.waitForSelector(`p a[href="https://github.com/${admin}"]`); + }); + }); +}); + +describe('User Settings when signed in as tester', () => { it('renders testable assistive technologies status and update on save', async () => { await getPage( { role: 'tester', url: '/account/settings' }, @@ -88,3 +100,18 @@ describe('User Settings common traits', () => { ); }); }); + +describe('User Settings when signed in as admin', () => { + it('renders admin actions section', async () => { + await getPage( + { role: 'admin', url: '/account/settings' }, + async (page, { consoleErrors }) => { + await page.waitForSelector( + 'button ::-p-text(Import Latest Test Plan Versions)' + ); + + expect(consoleErrors).toHaveLength(0); + } + ); + }); +});