diff --git a/.gitignore b/.gitignore index 50eb2d5dc..2ec1b6e1a 100644 --- a/.gitignore +++ b/.gitignore @@ -122,8 +122,13 @@ deploy/provision.retry # Migration generated files server/migrations/pg_dump_test_plan_target.sql server/migrations/test_plan_target_id.csv +server/migrations/dumps/dumpDatabase_*.sql +server/migrations/dumps/dumpTable_*.sql # Private Key files (installed by deploy) jwt-signing-key.pem client/resources + +#temp files for import-tests +server/scripts/import-tests/tmp diff --git a/client/components/AddTestToQueueWithConfirmation/index.jsx b/client/components/AddTestToQueueWithConfirmation/index.jsx index 54be4d16b..4002f3d2c 100644 --- a/client/components/AddTestToQueueWithConfirmation/index.jsx +++ b/client/components/AddTestToQueueWithConfirmation/index.jsx @@ -66,7 +66,13 @@ function AddTestToQueueWithConfirmation({ ); const existingTestPlanReports = - existingTestPlanReportsData?.existingTestPlanVersion?.testPlanReports; + existingTestPlanReportsData?.existingTestPlanVersion?.testPlanReports.filter( + tpr => + tpr.at?.id === at?.id && + tpr.browser?.id === browser?.id && + tpr.minimumAtVersion?.id === minimumAtVersion?.id && + tpr.exactAtVersion?.id === exactAtVersion?.id + ); let latestOldVersion; let oldReportToCopyResultsFrom; diff --git a/client/components/AddTestToQueueWithConfirmation/queries.js b/client/components/AddTestToQueueWithConfirmation/queries.js index fef0e528d..d81162459 100644 --- a/client/components/AddTestToQueueWithConfirmation/queries.js +++ b/client/components/AddTestToQueueWithConfirmation/queries.js @@ -13,10 +13,11 @@ export const EXISTING_TEST_PLAN_REPORTS = gql` query ExistingTestPlanReports($testPlanVersionId: ID!, $directory: String!) { existingTestPlanVersion: testPlanVersion(id: $testPlanVersionId) { id + metadata testPlanReports { id - markedFinalAt isFinal + markedFinalAt draftTestPlanRuns { initiatedByAutomation } @@ -27,7 +28,6 @@ export const EXISTING_TEST_PLAN_REPORTS = gql` id } } - metadata } oldTestPlanVersions: testPlanVersions( phases: [CANDIDATE, RECOMMENDED] @@ -35,6 +35,7 @@ export const EXISTING_TEST_PLAN_REPORTS = gql` ) { id updatedAt + metadata testPlanReports { id at { @@ -44,7 +45,6 @@ export const EXISTING_TEST_PLAN_REPORTS = gql` id } } - metadata } } `; diff --git a/client/components/App/queries.js b/client/components/App/queries.js index 793c404f5..a38247cf8 100644 --- a/client/components/App/queries.js +++ b/client/components/App/queries.js @@ -1,11 +1,11 @@ import { gql } from '@apollo/client'; +import { ME_FIELDS } from '@components/common/fragments'; export const ME_QUERY = gql` + ${ME_FIELDS} query Me { me { - id - username - roles + ...MeFields } } `; diff --git a/client/components/CandidateReview/CandidateTestPlanRun/index.jsx b/client/components/CandidateReview/CandidateTestPlanRun/index.jsx index 2123aeaa7..1e6c6dcbf 100644 --- a/client/components/CandidateReview/CandidateTestPlanRun/index.jsx +++ b/client/components/CandidateReview/CandidateTestPlanRun/index.jsx @@ -17,12 +17,11 @@ import Col from 'react-bootstrap/Col'; import Button from 'react-bootstrap/Button'; import { useParams, useNavigate, Navigate } from 'react-router-dom'; import { Helmet } from 'react-helmet'; -import { getMetrics } from 'shared'; +import { getMetrics, dates } from 'shared'; import './CandidateTestPlanRun.css'; import '../../TestRun/TestRun.css'; import '../../App/App.css'; import { useMediaQuery } from 'react-responsive'; -import { convertDateToString } from '../../../utils/formatter'; import TestPlanResultsTable from '../../common/TestPlanResultsTable'; import ProvideFeedbackModal from '../CandidateModals/ProvideFeedbackModal'; import ThankYouModal from '../CandidateModals/ThankYouModal'; @@ -31,6 +30,8 @@ import DisclosureComponent from '../../common/DisclosureComponent'; import createIssueLink, { getIssueSearchLink } from '../../../utils/createIssueLink'; +import RunHistory from '../../common/RunHistory'; +import { useUrlTestIndex } from '../../../hooks/useUrlTestIndex'; const CandidateTestPlanRun = () => { const { atId, testPlanVersionId } = useParams(); @@ -56,7 +57,8 @@ const CandidateTestPlanRun = () => { const [reviewStatus, setReviewStatus] = useState(''); const [firstTimeViewing, setFirstTimeViewing] = useState(false); const [viewedTests, setViewedTests] = useState([]); - const [currentTestIndex, setCurrentTestIndex] = useState(0); + const [testsLength, setTestsLength] = useState(0); + const [currentTestIndex, setCurrentTestIndex] = useUrlTestIndex(testsLength); const [showTestNavigator, setShowTestNavigator] = useState(true); const [isFirstTest, setIsFirstTest] = useState(true); const [isLastTest, setIsLastTest] = useState(false); @@ -64,6 +66,7 @@ const CandidateTestPlanRun = () => { const [thankYouModalShowing, setThankYouModalShowing] = useState(false); const [showInstructions, setShowInstructions] = useState(false); const [showBrowserBools, setShowBrowserBools] = useState([]); + const [showRunHistory, setShowRunHistory] = useState(false); const [showBrowserClicks, setShowBrowserClicks] = useState([]); const isLaptopOrLarger = useMediaQuery({ @@ -182,7 +185,7 @@ const CandidateTestPlanRun = () => { return bools; }); }); - + setTestsLength(tests.length); setShowBrowserClicks(browserClicks); } }, [data]); @@ -282,7 +285,7 @@ const CandidateTestPlanRun = () => { const reviewStatusText = vendorReviewStatusMap[reviewStatus]; - const targetCompletionDate = convertDateToString( + const targetCompletionDate = dates.convertDateToString( new Date(recommendedPhaseTargetDate), 'MMMM D, YYYY' ); @@ -376,7 +379,8 @@ const CandidateTestPlanRun = () => {

{`${currentTest.seq}. ${currentTest.title}`}{' '} - using {`${at}`} + using {`${at}`}{' '} + {`${testPlanReport?.latestAtVersionReleasedAt?.name ?? ''}`} {viewedTests.includes(currentTest.id) && !firstTimeViewing && ' '} {viewedTests.includes(currentTest.id) && !firstTimeViewing && ( @@ -392,9 +396,11 @@ const CandidateTestPlanRun = () => {
Candidate Test Plan:{' '} - {`${ - testPlanVersion.title || testPlanVersion.testPlan?.directory || '' - }`} + + {`${ + testPlanVersion.title || testPlanVersion.testPlan?.directory || '' + } ${testPlanVersion.versionString}`} +
@@ -461,13 +467,15 @@ const CandidateTestPlanRun = () => { 'Test Instructions', ...testPlanReports.map( testPlanReport => `Test Results for ${testPlanReport.browser.name}` - ) + ), + 'Run History' ]} onClick={[ () => setShowInstructions(!showInstructions), - ...showBrowserClicks + ...showBrowserClicks, + () => setShowRunHistory(!showRunHistory) ]} - expanded={[showInstructions, ...showBrowserBools]} + expanded={[showInstructions, ...showBrowserBools, showRunHistory]} disclosureContainerView={[ { /> ); - }) + }), + ]} stacked > diff --git a/client/components/CandidateReview/CandidateTestPlanRun/queries.js b/client/components/CandidateReview/CandidateTestPlanRun/queries.js index f375110af..f591896e2 100644 --- a/client/components/CandidateReview/CandidateTestPlanRun/queries.js +++ b/client/components/CandidateReview/CandidateTestPlanRun/queries.js @@ -1,4 +1,15 @@ import { gql } from '@apollo/client'; +import { + AT_FIELDS, + AT_VERSION_FIELDS, + BROWSER_FIELDS, + BROWSER_VERSION_FIELDS, + ISSUE_FIELDS, + ME_FIELDS, + SCENARIO_RESULT_FIELDS, + TEST_FIELDS, + TEST_RESULT_FIELDS +} from '@components/common/fragments'; export const ADD_VIEWER_MUTATION = gql` mutation AddViewerMutation($testPlanVersionId: ID!, $testId: ID!) { @@ -25,15 +36,22 @@ export const PROMOTE_VENDOR_REVIEW_STATUS_REPORT_MUTATION = gql` `; export const CANDIDATE_REPORTS_QUERY = gql` + ${AT_FIELDS} + ${AT_VERSION_FIELDS} + ${BROWSER_FIELDS} + ${BROWSER_VERSION_FIELDS} + ${ISSUE_FIELDS('all')} + ${ME_FIELDS} + ${TEST_FIELDS()} + ${TEST_RESULT_FIELDS} + ${SCENARIO_RESULT_FIELDS('all')} query CandidateReportsQuery( $atId: ID! $testPlanVersionId: ID $testPlanVersionIds: [ID] ) { me { - id - roles - username + ...MeFields } testPlanReports( atId: $atId @@ -45,104 +63,47 @@ export const CANDIDATE_REPORTS_QUERY = gql` id vendorReviewStatus issues { - author - isCandidateReview - feedbackType - testNumberFilteredByAt - link + ...IssueFieldsAll } at { - id - name + ...AtFields } latestAtVersionReleasedAt { - id - name - releasedAt + ...AtVersionFields } browser { - id - name + ...BrowserFields } testPlanVersion { id title phase gitSha - testPlan { - directory - } - metadata - testPageUrl - updatedAt versionString + updatedAt candidatePhaseReachedAt recommendedPhaseTargetDate + testPageUrl + metadata + testPlan { + directory + } } runnableTests { - id - title - rowNumber - renderedUrl + ...TestFieldsSimple renderableContent viewers { username } } finalizedTestResults { - id - completedAt + ...TestResultFields test { - id - rowNumber - title - renderedUrl + ...TestFieldsSimple renderableContent } scenarioResults { - id - scenario { - commands { - id - text - } - } - output - assertionResults { - id - assertion { - text - phrase - } - passed - } - mustAssertionResults: assertionResults(priority: MUST) { - assertion { - text - phrase - } - passed - } - shouldAssertionResults: assertionResults(priority: SHOULD) { - assertion { - text - phrase - } - passed - } - mayAssertionResults: assertionResults(priority: MAY) { - assertion { - text - phrase - } - passed - } - unexpectedBehaviors { - id - text - impact - details - } + ...ScenarioResultFieldsAll } } draftTestPlanRuns { @@ -153,18 +114,16 @@ export const CANDIDATE_REPORTS_QUERY = gql` id } testResults { + ...TestResultFields test { id } atVersion { - id - name + ...AtVersionFields } browserVersion { - id - name + ...BrowserVersionFields } - completedAt } } } diff --git a/client/components/CandidateReview/TestPlans/index.jsx b/client/components/CandidateReview/TestPlans/index.jsx index 5ae550b90..d6760e1f9 100644 --- a/client/components/CandidateReview/TestPlans/index.jsx +++ b/client/components/CandidateReview/TestPlans/index.jsx @@ -18,7 +18,7 @@ import { getTestPlanVersionTitle } from '@components/Reports/getTitles'; import ClippedProgressBar from '@components/common/ClippedProgressBar'; -import { convertDateToString } from '@client/utils/formatter'; +import { dates } from 'shared'; import './TestPlans.css'; import { calculations } from 'shared'; @@ -519,7 +519,7 @@ const TestPlans = ({ testPlanVersions }) => { - {convertDateToString( + {dates.convertDateToString( candidatePhaseReachedAt, 'MMM D, YYYY' )} @@ -527,7 +527,7 @@ const TestPlans = ({ testPlanVersions }) => { - {convertDateToString( + {dates.convertDateToString( recommendedPhaseTargetDate, 'MMM D, YYYY' )} diff --git a/client/components/CandidateReview/queries.js b/client/components/CandidateReview/queries.js index 4fd8ab8e2..c2041e400 100644 --- a/client/components/CandidateReview/queries.js +++ b/client/components/CandidateReview/queries.js @@ -1,51 +1,45 @@ import { gql } from '@apollo/client'; +import { + AT_FIELDS, + AT_VERSION_FIELDS, + BROWSER_FIELDS, + ISSUE_FIELDS +} from '@components/common/fragments'; export const CANDIDATE_REVIEW_PAGE_QUERY = gql` + ${AT_FIELDS} + ${AT_VERSION_FIELDS} + ${BROWSER_FIELDS} + ${ISSUE_FIELDS()} query { testPlanVersions(phases: [CANDIDATE]) { id - phase title + phase gitSha - testPlan { - directory - } - metadata versionString + updatedAt candidatePhaseReachedAt recommendedPhaseTargetDate + metadata + testPlan { + directory + } testPlanReports(isFinal: true) { id metrics + vendorReviewStatus at { - id - name + ...AtFields } latestAtVersionReleasedAt { - id - name - releasedAt + ...AtVersionFields } browser { - id - name - } - testPlanVersion { - id - title - gitSha - testPlan { - directory - } - metadata - updatedAt + ...BrowserFields } - vendorReviewStatus issues { - link - isOpen - isCandidateReview - feedbackType + ...IssueFieldsSimple } } } diff --git a/client/components/DataManagement/DataManagementRow/index.jsx b/client/components/DataManagement/DataManagementRow/index.jsx index e597f5dfd..981c89e05 100644 --- a/client/components/DataManagement/DataManagementRow/index.jsx +++ b/client/components/DataManagement/DataManagementRow/index.jsx @@ -8,11 +8,7 @@ import { UPDATE_TEST_PLAN_VERSION_RECOMMENDED_TARGET_DATE } from '../queries'; import { LoadingStatus, useTriggerLoad } from '../../common/LoadingStatus'; -import { - checkDaysBetweenDates, - convertDateToString, - convertStringFormatToAnotherFormat -} from '../../../utils/formatter'; +import { dates } from 'shared'; import { derivePhaseName } from '@client/utils/aria'; import { THEMES, useThemedModal } from '@client/hooks/useThemedModal'; import BasicModal from '@components/common/BasicModal'; @@ -23,6 +19,11 @@ import VersionString from '../../common/VersionString'; import PhasePill from '../../common/PhasePill'; import { differenceBy, uniq as unique, uniqBy as uniqueBy } from 'lodash'; import { getVersionData } from '../utils'; +import { + AtPropType, + TestPlanPropType, + TestPlanVersionPropType +} from '../../common/proptypes'; const StatusCell = styled.div` display: flex; @@ -301,7 +302,7 @@ const DataManagementRow = ({ variables: { testPlanVersionId: updateTargetModalData.testPlanVersionId, recommendedPhaseTargetDate: - convertStringFormatToAnotherFormat(updatedDateText) + dates.convertStringFormatToAnotherFormat(updatedDateText) } }); const updatedTestPlanVersion = @@ -373,7 +374,7 @@ const DataManagementRow = ({ break; } - const dateString = convertDateToString(versionDate, 'MMM D, YYYY'); + const dateString = dates.convertDateToString(versionDate, 'MMM D, YYYY'); return ( <> @@ -647,7 +648,9 @@ const DataManagementRow = ({ Review Completed  - {convertDateToString(completionDate, 'MMM D, YYYY')} + + {dates.convertDateToString(completionDate, 'MMM D, YYYY')} + ); @@ -776,7 +779,9 @@ const DataManagementRow = ({ Review Completed  - {convertDateToString(completionDate, 'MMM D, YYYY')} + + {dates.convertDateToString(completionDate, 'MMM D, YYYY')} + ); @@ -837,7 +842,7 @@ const DataManagementRow = ({ const candidatePhaseReachedDate = new Date( latestVersion.candidatePhaseReachedAt ); - const daysInReview = checkDaysBetweenDates( + const daysInReview = dates.checkDaysBetweenDates( currentDate, candidatePhaseReachedDate ); @@ -846,13 +851,13 @@ const DataManagementRow = ({ let timeToTargetDate = 0; if (currentDate > recommendedPhaseTargetDate) { // Indicates that this is in the past - timeToTargetDate = checkDaysBetweenDates( + timeToTargetDate = dates.checkDaysBetweenDates( currentDate, recommendedPhaseTargetDate ); timeToTargetDate = -timeToTargetDate; } else - timeToTargetDate = checkDaysBetweenDates( + timeToTargetDate = dates.checkDaysBetweenDates( recommendedPhaseTargetDate, currentDate ); @@ -984,7 +989,7 @@ const DataManagementRow = ({ Approved  - {convertDateToString(completionDate, 'MMM D, YYYY')} + {dates.convertDateToString(completionDate, 'MMM D, YYYY')} ); @@ -1089,32 +1094,16 @@ const DataManagementRow = ({ DataManagementRow.propTypes = { isAdmin: PropTypes.bool, - ats: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string, - name: PropTypes.string - }) - ), - testPlan: PropTypes.shape({ - id: PropTypes.string, - title: PropTypes.string, - directory: PropTypes.string - }).isRequired, + ats: PropTypes.arrayOf(AtPropType), + testPlan: TestPlanPropType.isRequired, testPlanVersions: PropTypes.arrayOf( PropTypes.shape({ - id: PropTypes.string, + ...TestPlanVersionPropType, + // Optional in this component title: PropTypes.string, - phase: PropTypes.string, - gitSha: PropTypes.string, - testPlan: PropTypes.shape({ - directory: PropTypes.string - }), - updatedAt: PropTypes.string, - draftPhaseReachedAt: PropTypes.string, - candidatePhaseReachedAt: PropTypes.string, - recommendedPhaseReachedAt: PropTypes.string + isRequired: PropTypes.bool }) - ).isRequired, + ), tableRowIndex: PropTypes.number.isRequired, setTestPlanVersions: PropTypes.func }; diff --git a/client/components/DataManagement/queries.js b/client/components/DataManagement/queries.js index 734b20f50..c86b90191 100644 --- a/client/components/DataManagement/queries.js +++ b/client/components/DataManagement/queries.js @@ -1,26 +1,38 @@ import { gql } from '@apollo/client'; +import { + AT_FIELDS, + AT_VERSION_FIELDS, + BROWSER_FIELDS, + BROWSER_VERSION_FIELDS, + ISSUE_FIELDS, + ME_FIELDS, + TEST_PLAN_FIELDS, + TEST_PLAN_REPORT_FIELDS, + TEST_PLAN_VERSION_FIELDS, + TEST_RESULT_FIELDS +} from '@components/common/fragments'; export const DATA_MANAGEMENT_PAGE_QUERY = gql` + ${AT_FIELDS} + ${AT_VERSION_FIELDS} + ${BROWSER_FIELDS} + ${BROWSER_VERSION_FIELDS} + ${ISSUE_FIELDS()} + ${ME_FIELDS} + ${TEST_PLAN_FIELDS} + ${TEST_PLAN_REPORT_FIELDS} + ${TEST_RESULT_FIELDS} query DataManagementPage { me { - id - username - roles + ...MeFields } ats { - id - key - name + ...AtFields browsers { - id - key - name + ...BrowserFields } atVersions { - id - name - releasedAt - supportedByAutomation + ...AtVersionFields } candidateBrowsers { id @@ -30,9 +42,7 @@ export const DATA_MANAGEMENT_PAGE_QUERY = gql` } } testPlans { - id - directory - title + ...TestPlanFields } deprecatedTestPlanVersions: testPlanVersions(phases: [DEPRECATED]) { id @@ -59,28 +69,20 @@ export const DATA_MANAGEMENT_PAGE_QUERY = gql` candidatePhaseReachedAt recommendedPhaseTargetDate recommendedPhaseReachedAt + metadata testPlan { directory } testPlanReports { - id - metrics - isFinal - markedFinalAt + ...TestPlanReportFields at { - id - key - name + ...AtFields } browser { - id - key - name + ...BrowserFields } issues { - link - isOpen - feedbackType + ...IssueFieldsSimple } draftTestPlanRuns { tester { @@ -90,27 +92,28 @@ export const DATA_MANAGEMENT_PAGE_QUERY = gql` id } testResults { + ...TestResultFields test { id } atVersion { - id - name + ...AtVersionFields } browserVersion { - id - name + ...BrowserVersionFields } - completedAt } } } - metadata } } `; export const UPDATE_TEST_PLAN_VERSION_PHASE = gql` + ${AT_FIELDS} + ${BROWSER_FIELDS} + ${ISSUE_FIELDS()} + ${TEST_PLAN_VERSION_FIELDS} mutation UpdateTestPlanVersionPhase( $testPlanVersionId: ID! $phase: TestPlanVersionPhase! @@ -122,39 +125,19 @@ export const UPDATE_TEST_PLAN_VERSION_PHASE = gql` testPlanVersionDataToIncludeId: $testPlanVersionDataToIncludeId ) { testPlanVersion { - id - title - phase - gitSha - gitMessage - versionString - updatedAt - draftPhaseReachedAt - candidatePhaseReachedAt - recommendedPhaseTargetDate - recommendedPhaseReachedAt - testPlan { - directory - } + ...TestPlanVersionFields testPlanReports { id at { - id - key - name + ...AtFields } browser { - id - key - name + ...BrowserFields } issues { - link - isOpen - feedbackType + ...IssueFieldsSimple } } - metadata } } } @@ -162,6 +145,10 @@ export const UPDATE_TEST_PLAN_VERSION_PHASE = gql` `; export const UPDATE_TEST_PLAN_VERSION_RECOMMENDED_TARGET_DATE = gql` + ${AT_FIELDS} + ${BROWSER_FIELDS} + ${ISSUE_FIELDS()} + ${TEST_PLAN_VERSION_FIELDS} mutation UpdateTestPlanReportRecommendedTargetDate( $testPlanVersionId: ID! $recommendedPhaseTargetDate: Timestamp! @@ -171,39 +158,19 @@ export const UPDATE_TEST_PLAN_VERSION_RECOMMENDED_TARGET_DATE = gql` recommendedPhaseTargetDate: $recommendedPhaseTargetDate ) { testPlanVersion { - id - title - phase - gitSha - gitMessage - versionString - updatedAt - draftPhaseReachedAt - candidatePhaseReachedAt - recommendedPhaseTargetDate - recommendedPhaseReachedAt - testPlan { - directory - } + ...TestPlanVersionFields testPlanReports { id at { - id - key - name + ...AtFields } browser { - id - key - name + ...BrowserFields } issues { - link - isOpen - feedbackType + ...IssueFieldsSimple } } - metadata } } } diff --git a/client/components/ManageBotRunDialog/MarkBotRunFinishedButton/index.jsx b/client/components/ManageBotRunDialog/MarkBotRunFinishedButton/index.jsx index bcec9dd67..6a8fdec5d 100644 --- a/client/components/ManageBotRunDialog/MarkBotRunFinishedButton/index.jsx +++ b/client/components/ManageBotRunDialog/MarkBotRunFinishedButton/index.jsx @@ -10,6 +10,7 @@ import { LoadingStatus, useTriggerLoad } from '../../common/LoadingStatus'; import { useTestPlanRunValidatedAssertionCounts } from '../../../hooks/useTestPlanRunValidatedAssertionCounts'; import BasicModal from '../../common/BasicModal'; import { useTestPlanRunIsFinished } from '../../../hooks/useTestPlanRunIsFinished'; +import { TestPlanRunPropType } from '../../common/proptypes'; const MarkBotRunFinishedButton = ({ testPlanRun, onClick = () => {} }) => { const { @@ -86,7 +87,7 @@ const MarkBotRunFinishedButton = ({ testPlanRun, onClick = () => {} }) => { }; MarkBotRunFinishedButton.propTypes = { - testPlanRun: PropTypes.object.isRequired, + testPlanRun: TestPlanRunPropType.isRequired, onClick: PropTypes.func }; diff --git a/client/components/ManageBotRunDialog/RetryCanceledCollectionsButton/index.jsx b/client/components/ManageBotRunDialog/RetryCanceledCollectionsButton/index.jsx index a842b8142..947b480dd 100644 --- a/client/components/ManageBotRunDialog/RetryCanceledCollectionsButton/index.jsx +++ b/client/components/ManageBotRunDialog/RetryCanceledCollectionsButton/index.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { Button } from 'react-bootstrap'; import { useMutation } from '@apollo/client'; import { RETRY_CANCELED_COLLECTIONS } from '../queries'; +import { CollectionJobPropType } from '../../common/proptypes'; const RetryCanceledCollectionsButton = ({ collectionJob, @@ -33,16 +34,7 @@ const RetryCanceledCollectionsButton = ({ }; RetryCanceledCollectionsButton.propTypes = { - collectionJob: PropTypes.shape({ - id: PropTypes.string, - status: PropTypes.oneOf([ - 'QUEUED', - 'RUNNING', - 'CANCELLED', - 'COMPLETED', - 'ERROR' - ]) - }), + collectionJob: CollectionJobPropType, onClick: PropTypes.func }; diff --git a/client/components/ManageBotRunDialog/StopRunningCollectionButton/index.jsx b/client/components/ManageBotRunDialog/StopRunningCollectionButton/index.jsx index b985996fd..a1fa69c61 100644 --- a/client/components/ManageBotRunDialog/StopRunningCollectionButton/index.jsx +++ b/client/components/ManageBotRunDialog/StopRunningCollectionButton/index.jsx @@ -4,6 +4,7 @@ import { Button } from 'react-bootstrap'; import { useMutation } from '@apollo/client'; import { CANCEL_COLLECTION_JOB } from '../queries'; import { LoadingStatus, useTriggerLoad } from '../../common/LoadingStatus'; +import { CollectionJobPropType } from '../../common/proptypes'; const StopRunningCollectionButton = ({ collectionJob, onClick = () => {} }) => { if (!collectionJob) { @@ -44,16 +45,7 @@ const StopRunningCollectionButton = ({ collectionJob, onClick = () => {} }) => { }; StopRunningCollectionButton.propTypes = { - collectionJob: PropTypes.shape({ - id: PropTypes.string, - status: PropTypes.oneOf([ - 'QUEUED', - 'RUNNING', - 'CANCELLED', - 'COMPLETED', - 'ERROR' - ]).isRequired - }), + collectionJob: CollectionJobPropType, onClick: PropTypes.func }; diff --git a/client/components/ManageBotRunDialog/WithButton.jsx b/client/components/ManageBotRunDialog/WithButton.jsx index ea6f9018a..1eac6318a 100644 --- a/client/components/ManageBotRunDialog/WithButton.jsx +++ b/client/components/ManageBotRunDialog/WithButton.jsx @@ -5,6 +5,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faRobot } from '@fortawesome/free-solid-svg-icons'; import ManageBotRunDialog from '.'; import { useTestPlanRunIsFinished } from '../../hooks/useTestPlanRunIsFinished'; +import { TestPlanRunPropType, UserPropType } from '../common/proptypes'; const ManageBotRunDialogWithButton = ({ testPlanRun, @@ -49,10 +50,10 @@ const ManageBotRunDialogWithButton = ({ }; ManageBotRunDialogWithButton.propTypes = { - testPlanRun: PropTypes.object.isRequired, + testPlanRun: TestPlanRunPropType.isRequired, testPlanReportId: PropTypes.string.isRequired, runnableTestsLength: PropTypes.number.isRequired, - testers: PropTypes.array.isRequired, + testers: PropTypes.arrayOf(UserPropType).isRequired, onChange: PropTypes.func.isRequired }; diff --git a/client/components/ManageBotRunDialog/index.jsx b/client/components/ManageBotRunDialog/index.jsx index 154a8db6b..8915ad55b 100644 --- a/client/components/ManageBotRunDialog/index.jsx +++ b/client/components/ManageBotRunDialog/index.jsx @@ -16,6 +16,7 @@ import MarkBotRunFinishedButton from './MarkBotRunFinishedButton'; import RetryCanceledCollectionsButton from './RetryCanceledCollectionsButton'; import StopRunningCollectionButton from './StopRunningCollectionButton'; import ViewLogsButton from './ViewLogsButton'; +import { TestPlanRunPropType, UserPropType } from '../common/proptypes'; const ManageBotRunDialog = ({ testPlanReportId, @@ -177,10 +178,10 @@ const ManageBotRunDialog = ({ }; ManageBotRunDialog.propTypes = { - testPlanRun: PropTypes.object.isRequired, + testPlanRun: TestPlanRunPropType.isRequired, show: PropTypes.bool.isRequired, setShow: PropTypes.func.isRequired, - testers: PropTypes.array.isRequired, + testers: PropTypes.arrayOf(UserPropType).isRequired, testPlanReportId: PropTypes.string.isRequired, runnableTestsLength: PropTypes.number.isRequired, onChange: PropTypes.func.isRequired diff --git a/client/components/ManageTestQueue/AddTestPlans.jsx b/client/components/ManageTestQueue/AddTestPlans.jsx index cfd929294..eb93ada74 100644 --- a/client/components/ManageTestQueue/AddTestPlans.jsx +++ b/client/components/ManageTestQueue/AddTestPlans.jsx @@ -3,7 +3,7 @@ import { Form } from 'react-bootstrap'; import RadioBox from '@components/common/RadioBox'; import AddTestToQueueWithConfirmation from '@components/AddTestToQueueWithConfirmation'; import { DisclosureContainer } from '@components/ManageTestQueue/index'; -import { gitUpdatedDateToString } from '@client/utils/gitUtils'; +import { dates } from 'shared'; import PropTypes from 'prop-types'; const AddTestPlans = ({ @@ -162,8 +162,8 @@ const AddTestPlans = ({ {matchingTestPlanVersions.length ? ( matchingTestPlanVersions.map(item => ( )) ) : ( diff --git a/client/components/ManageTestQueue/ManageAtVersions.jsx b/client/components/ManageTestQueue/ManageAtVersions.jsx index 289293780..65beea962 100644 --- a/client/components/ManageTestQueue/ManageAtVersions.jsx +++ b/client/components/ManageTestQueue/ManageAtVersions.jsx @@ -5,7 +5,7 @@ import { faEdit, faTrashAlt } from '@fortawesome/free-solid-svg-icons'; import { DisclosureContainer } from '@components/ManageTestQueue/index'; import BasicModal from '@components/common/BasicModal'; import UpdateVersionModal from '@components/common/UpdateVersionModal'; -import { convertStringToDate } from '@client/utils/formatter'; +import { dates } from 'shared'; import { useMutation } from '@apollo/client'; import { ADD_AT_VERSION_MUTATION, @@ -15,6 +15,7 @@ import { import { useTriggerLoad } from '@components/common/LoadingStatus'; import { THEMES, useThemedModal } from '@client/hooks/useThemedModal'; import PropTypes from 'prop-types'; +import { AtPropType } from '../common/proptypes'; const ManageAtVersions = ({ ats = [], triggerUpdate = () => {} }) => { const { triggerLoad } = useTriggerLoad(); @@ -204,7 +205,7 @@ const ManageAtVersions = ({ ats = [], triggerUpdate = () => {} }) => { variables: { atId: selectedAtId, name: updatedVersionText, - releasedAt: convertStringToDate(updatedDateAvailabilityText) + releasedAt: dates.convertStringToDate(updatedDateAvailabilityText) } }); setSelectedAtVersionId( @@ -232,7 +233,7 @@ const ManageAtVersions = ({ ats = [], triggerUpdate = () => {} }) => { variables: { atVersionId: selectedAtVersionId, name: updatedVersionText, - releasedAt: convertStringToDate(updatedDateAvailabilityText) + releasedAt: dates.convertStringToDate(updatedDateAvailabilityText) } }); await triggerUpdate(); @@ -410,20 +411,7 @@ const ManageAtVersions = ({ ats = [], triggerUpdate = () => {} }) => { }; ManageAtVersions.propTypes = { - ats: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - key: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - browsers: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - key: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }) - ).isRequired - }) - ).isRequired, + ats: PropTypes.arrayOf(AtPropType).isRequired, triggerUpdate: PropTypes.func }; diff --git a/client/components/ManageTestQueue/index.jsx b/client/components/ManageTestQueue/index.jsx index d5aa795af..3bf82420d 100644 --- a/client/components/ManageTestQueue/index.jsx +++ b/client/components/ManageTestQueue/index.jsx @@ -5,6 +5,7 @@ import { LoadingStatus, useTriggerLoad } from '../common/LoadingStatus'; import DisclosureComponent from '../common/DisclosureComponent'; import ManageAtVersions from '@components/ManageTestQueue/ManageAtVersions'; import AddTestPlans from '@components/ManageTestQueue/AddTestPlans'; +import { AtPropType, TestPlanVersionPropType } from '../common/proptypes'; export const DisclosureContainer = styled.div` // Following directives are related to the ManageTestQueue component @@ -148,21 +149,8 @@ const ManageTestQueue = ({ }; ManageTestQueue.propTypes = { - ats: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - key: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - browsers: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - key: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }) - ).isRequired - }) - ).isRequired, - testPlanVersions: PropTypes.array, + ats: PropTypes.arrayOf(AtPropType).isRequired, + testPlanVersions: PropTypes.arrayOf(TestPlanVersionPropType), triggerUpdate: PropTypes.func }; diff --git a/client/components/ManageTestQueue/queries.js b/client/components/ManageTestQueue/queries.js index ac5cddf93..82ed8a3da 100644 --- a/client/components/ManageTestQueue/queries.js +++ b/client/components/ManageTestQueue/queries.js @@ -1,18 +1,19 @@ import { gql } from '@apollo/client'; +import { AT_VERSION_FIELDS } from '@components/common/fragments'; export const ADD_AT_VERSION_MUTATION = gql` + ${AT_VERSION_FIELDS} mutation AddAtVersion($atId: ID!, $name: String!, $releasedAt: Timestamp!) { at(id: $atId) { findOrCreateAtVersion(input: { name: $name, releasedAt: $releasedAt }) { - id - name - releasedAt + ...AtVersionFields } } } `; export const EDIT_AT_VERSION_MUTATION = gql` + ${AT_VERSION_FIELDS} mutation EditAtVersion( $atVersionId: ID! $name: String! @@ -20,9 +21,7 @@ export const EDIT_AT_VERSION_MUTATION = gql` ) { atVersion(id: $atVersionId) { updateAtVersion(input: { name: $name, releasedAt: $releasedAt }) { - id - name - releasedAt + ...AtVersionFields } } } @@ -38,11 +37,9 @@ export const DELETE_AT_VERSION_MUTATION = gql` id title } - # To be used when listing the conflicting results testResult { id } - # To be used when providing more details on the conflicting results testPlanReport { at { name diff --git a/client/components/Reports/SummarizeTestPlanReport.jsx b/client/components/Reports/SummarizeTestPlanReport.jsx index cda558bc9..4ea667860 100644 --- a/client/components/Reports/SummarizeTestPlanReport.jsx +++ b/client/components/Reports/SummarizeTestPlanReport.jsx @@ -11,14 +11,18 @@ import { faHome } from '@fortawesome/free-solid-svg-icons'; import styled from '@emotion/styled'; -import { getMetrics } from 'shared'; +import { getMetrics, dates } from 'shared'; import { none } from './None'; -import { convertDateToString } from '../../utils/formatter'; import DisclaimerInfo from '../DisclaimerInfo'; import TestPlanResultsTable from '../common/TestPlanResultsTable'; import DisclosureComponent from '../common/DisclosureComponent'; import { Link, Navigate, useLocation, useParams } from 'react-router-dom'; import createIssueLink from '../../utils/createIssueLink'; +import RunHistory from '../common/RunHistory'; +import { + TestPlanReportPropType, + TestPlanVersionPropType +} from '../common/proptypes'; const ResultsContainer = styled.div` padding: 1em 1.75em; @@ -28,54 +32,6 @@ const ResultsContainer = styled.div` margin-bottom: 0.5em; `; -const getTestersRunHistory = ( - testPlanReport, - testId, - draftTestPlanRuns = [] -) => { - const { id: testPlanReportId, at, browser } = testPlanReport; - let lines = []; - - draftTestPlanRuns.forEach(draftTestPlanRun => { - const { testPlanReport, testResults, tester } = draftTestPlanRun; - - const testResult = testResults.find(item => item.test.id === testId); - if (testPlanReportId === testPlanReport.id && testResult?.completedAt) { - lines.push( -
  • - Tested with{' '} - - {at.name} {testResult.atVersion.name} - {' '} - and{' '} - - {browser.name} {testResult.browserVersion.name} - {' '} - by{' '} - - - {tester.username} - - {' '} - on {convertDateToString(testResult.completedAt, 'MMMM DD, YYYY')}. -
  • - ); - } - }); - - return ( -
      - {lines} -
    - ); -}; - const SummarizeTestPlanReport = ({ testPlanVersion, testPlanReports }) => { const { exampleUrl, designPatternUrl } = testPlanVersion.metadata; const location = useLocation(); @@ -267,7 +223,7 @@ const SummarizeTestPlanReport = ({ testPlanVersion, testPlanReports }) => {
  • Report completed on{' '} - {convertDateToString( + {dates.convertDateToString( new Date(testPlanReport.markedFinalAt), 'MMMM D, YYYY' )} @@ -364,11 +320,12 @@ const SummarizeTestPlanReport = ({ testPlanVersion, testPlanReports }) => { + } /> ); @@ -378,60 +335,8 @@ const SummarizeTestPlanReport = ({ testPlanVersion, testPlanReports }) => { }; SummarizeTestPlanReport.propTypes = { - testPlanVersion: PropTypes.object.isRequired, - testPlanReports: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - runnableTests: PropTypes.arrayOf(PropTypes.object.isRequired).isRequired, - at: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }).isRequired, - browser: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }).isRequired, - finalizedTestResults: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - test: PropTypes.shape({ - title: PropTypes.string.isRequired, - renderedUrl: PropTypes.string.isRequired - }).isRequired, - scenarioResults: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - output: PropTypes.string.isRequired, - assertionResults: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - passed: PropTypes.bool.isRequired, - assertion: PropTypes.shape({ - text: PropTypes.string.isRequired - }).isRequired - }).isRequired - ).isRequired, - unexpectedBehaviors: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - text: PropTypes.string.isRequired, - impact: PropTypes.string.isRequired, - details: PropTypes.string.isRequired - }).isRequired - ).isRequired - }).isRequired - ).isRequired - }).isRequired - ).isRequired, - draftTestPlanRuns: PropTypes.arrayOf( - PropTypes.shape({ - tester: PropTypes.shape({ - username: PropTypes.string.isRequired - }) - }) - ) - }).isRequired - ) + testPlanVersion: TestPlanVersionPropType.isRequired, + testPlanReports: PropTypes.arrayOf(TestPlanReportPropType).isRequired }; export default SummarizeTestPlanReport; diff --git a/client/components/Reports/SummarizeTestPlanReports.jsx b/client/components/Reports/SummarizeTestPlanReports.jsx index 26867cd5a..ee3e4bbf7 100644 --- a/client/components/Reports/SummarizeTestPlanReports.jsx +++ b/client/components/Reports/SummarizeTestPlanReports.jsx @@ -9,6 +9,7 @@ import { derivePhaseName } from '../../utils/aria'; import { none } from './None'; import { getTestPlanTargetTitle, getTestPlanVersionTitle } from './getTitles'; import ClippedProgressBar from '@components/common/ClippedProgressBar'; +import { TestPlanVersionPropType } from '../common/proptypes'; const FullHeightContainer = styled(Container)` min-height: calc(100vh - 64px); @@ -151,26 +152,7 @@ const SummarizeTestPlanReports = ({ testPlanVersions }) => { }; SummarizeTestPlanReports.propTypes = { - testPlanVersions: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - phase: PropTypes.string.isRequired, - gitSha: PropTypes.string, - testPlan: PropTypes.shape({ - directory: PropTypes.string - }), - metadata: PropTypes.object, - testPlanReports: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - metrics: PropTypes.object.isRequired, - at: PropTypes.object.isRequired, - browser: PropTypes.object.isRequired - }) - ) - }) - ).isRequired + testPlanVersions: PropTypes.arrayOf(TestPlanVersionPropType).isRequired }; export default SummarizeTestPlanReports; diff --git a/client/components/Reports/SummarizeTestPlanVersion.jsx b/client/components/Reports/SummarizeTestPlanVersion.jsx index 427980839..74005bda1 100644 --- a/client/components/Reports/SummarizeTestPlanVersion.jsx +++ b/client/components/Reports/SummarizeTestPlanVersion.jsx @@ -2,7 +2,7 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { Helmet } from 'react-helmet'; import { none } from './None'; -import { getMetrics } from 'shared'; +import { getMetrics, dates } from 'shared'; import { getTestPlanTargetTitle, getTestPlanVersionTitle } from './getTitles'; import { Breadcrumb, Button, Container, Table } from 'react-bootstrap'; import { LinkContainer } from 'react-router-bootstrap'; @@ -11,7 +11,10 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faHome } from '@fortawesome/free-solid-svg-icons'; import styled from '@emotion/styled'; import DisclaimerInfo from '../DisclaimerInfo'; -import { convertDateToString } from '../../utils/formatter'; +import { + TestPlanReportPropType, + TestPlanVersionPropType +} from '../common/proptypes'; const FullHeightContainer = styled(Container)` min-height: calc(100vh - 64px); @@ -111,7 +114,7 @@ const SummarizeTestPlanVersion = ({ testPlanVersion, testPlanReports }) => {

    {getTestPlanTargetTitle(testPlanTarget)}

    Report completed on{' '} - {convertDateToString( + {dates.convertDateToString( new Date(testPlanReport.markedFinalAt), 'MMMM D, YYYY' )} @@ -184,26 +187,8 @@ const SummarizeTestPlanVersion = ({ testPlanVersion, testPlanReports }) => { }; SummarizeTestPlanVersion.propTypes = { - testPlanVersion: PropTypes.shape({ - gitSha: PropTypes.string, - testPlan: PropTypes.object, - directory: PropTypes.string, - versionString: PropTypes.string, - id: PropTypes.string.isRequired, - title: PropTypes.string, - phase: PropTypes.string, - metadata: PropTypes.shape({ - exampleUrl: PropTypes.string.isRequired, - designPatternUrl: PropTypes.string - }).isRequired - }).isRequired, - testPlanReports: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - runnableTests: PropTypes.arrayOf(PropTypes.object).isRequired, - finalizedTestResults: PropTypes.arrayOf(PropTypes.object) - }).isRequired - ).isRequired + testPlanVersion: TestPlanVersionPropType.isRequired, + testPlanReports: PropTypes.arrayOf(TestPlanReportPropType).isRequired }; export default SummarizeTestPlanVersion; diff --git a/client/components/Reports/queries.js b/client/components/Reports/queries.js index 744992153..5d4d5cf52 100644 --- a/client/components/Reports/queries.js +++ b/client/components/Reports/queries.js @@ -1,6 +1,17 @@ import { gql } from '@apollo/client'; +import { + AT_FIELDS, + AT_VERSION_FIELDS, + BROWSER_FIELDS, + BROWSER_VERSION_FIELDS, + SCENARIO_RESULT_FIELDS, + TEST_FIELDS, + TEST_RESULT_FIELDS +} from '@components/common/fragments'; export const REPORTS_PAGE_QUERY = gql` + ${AT_FIELDS} + ${BROWSER_FIELDS} query ReportsPageQuery { testPlanVersions(phases: [CANDIDATE, RECOMMENDED]) { id @@ -8,20 +19,19 @@ export const REPORTS_PAGE_QUERY = gql` phase gitSha updatedAt + versionString + metadata testPlan { directory } - metadata testPlanReports(isFinal: true) { id metrics at { - id - name + ...AtFields } browser { - id - name + ...BrowserFields } } } @@ -29,97 +39,54 @@ export const REPORTS_PAGE_QUERY = gql` `; export const REPORT_PAGE_QUERY = gql` + ${AT_FIELDS} + ${AT_VERSION_FIELDS} + ${BROWSER_FIELDS} + ${BROWSER_VERSION_FIELDS} + ${SCENARIO_RESULT_FIELDS('all')} + ${TEST_FIELDS()} + ${TEST_RESULT_FIELDS} query ReportPageQuery($testPlanVersionId: ID) { testPlanVersion(id: $testPlanVersionId) { id title phase gitSha + updatedAt versionString + metadata testPlan { directory } - metadata testPlanReports(isFinal: true) { id metrics markedFinalAt at { - id - name + ...AtFields } browser { - id - name + ...BrowserFields } recommendedAtVersion { - id - name - releasedAt + ...AtVersionFields } runnableTests { - id - title - renderedUrl + ...TestFieldsSimple } finalizedTestResults { - id + ...TestResultFields test { - id - rowNumber - title - renderedUrl + ...TestFieldsSimple } scenarioResults { - id - scenario { - commands { - id - text - } - } - output - assertionResults { - id - assertion { - text - phrase - } - passed - } - mustAssertionResults: assertionResults(priority: MUST) { - assertion { - text - phrase - } - passed - } - shouldAssertionResults: assertionResults(priority: SHOULD) { - assertion { - text - phrase - } - passed - } - mayAssertionResults: assertionResults(priority: MAY) { - assertion { - text - phrase - } - passed - } - unexpectedBehaviors { - id - text - impact - details - } + ...ScenarioResultFieldsAll } atVersion { - name + ...AtVersionFields } browserVersion { - name + ...BrowserVersionFields } } draftTestPlanRuns { @@ -130,18 +97,16 @@ export const REPORT_PAGE_QUERY = gql` id } testResults { + ...TestResultFields test { id } atVersion { - id - name + ...AtVersionFields } browserVersion { - id - name + ...BrowserVersionFields } - completedAt } } } diff --git a/client/components/ReviewConflicts/ReviewConflicts.jsx b/client/components/ReviewConflicts/ReviewConflicts.jsx index c97740dc2..f272c5663 100644 --- a/client/components/ReviewConflicts/ReviewConflicts.jsx +++ b/client/components/ReviewConflicts/ReviewConflicts.jsx @@ -2,6 +2,7 @@ import React, { useEffect, useRef } from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; import TurndownService from 'turndown'; +import { TestPlanReportPropType, TestPropType } from '../common/proptypes'; const Wrapper = styled.div` & h2 { @@ -119,58 +120,8 @@ const ReviewConflicts = ({ }; ReviewConflicts.propTypes = { - testPlanReport: PropTypes.shape({ - id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - conflicts: PropTypes.arrayOf( - PropTypes.shape({ - source: PropTypes.shape({ - test: PropTypes.shape({ - id: PropTypes.string.isRequired - }).isRequired, - scenario: PropTypes.shape({ - id: PropTypes.string.isRequired, - commands: PropTypes.arrayOf( - PropTypes.shape({ - text: PropTypes.string.isRequired - }) - ).isRequired - }).isRequired, - assertion: PropTypes.shape({ - id: PropTypes.string.isRequired, - text: PropTypes.string.isRequired - }) - }).isRequired, - conflictingResults: PropTypes.arrayOf( - PropTypes.shape({ - testPlanRun: PropTypes.shape({ - id: PropTypes.string.isRequired, - tester: PropTypes.shape({ - username: PropTypes.string.isRequired - }).isRequired - }).isRequired, - scenarioResult: PropTypes.shape({ - output: PropTypes.string.isRequired, - unexpectedBehaviors: PropTypes.arrayOf( - PropTypes.shape({ - text: PropTypes.string.isRequired, - impact: PropTypes.string.isRequired, - details: PropTypes.string.isRequired - }) - ).isRequired - }), - assertionResult: PropTypes.shape({ - passed: PropTypes.bool.isRequired - }) - }) - ).isRequired - }) - ).isRequired - }), - test: PropTypes.shape({ - id: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - rowNumber: PropTypes.number.isRequired - }), + testPlanReport: TestPlanReportPropType.isRequired, + test: TestPropType.isRequired, hideHeadline: PropTypes.bool, conflictMarkdownRef: PropTypes.shape({ current: PropTypes.string diff --git a/client/components/TestPlanReportStatusDialog/index.jsx b/client/components/TestPlanReportStatusDialog/index.jsx index 37d109f0a..7bd981b0b 100644 --- a/client/components/TestPlanReportStatusDialog/index.jsx +++ b/client/components/TestPlanReportStatusDialog/index.jsx @@ -9,6 +9,7 @@ import BasicModal from '../common/BasicModal'; import './TestPlanReportStatusDialog.css'; import ReportStatusSummary from '../common/ReportStatusSummary'; import { AtVersion } from '../common/AtBrowserVersion'; +import { TestPlanVersionPropType } from '../common/proptypes'; const TestPlanReportStatusDialog = ({ testPlanVersion, @@ -147,37 +148,7 @@ const TestPlanReportStatusDialog = ({ }; TestPlanReportStatusDialog.propTypes = { - testPlanVersion: PropTypes.shape({ - id: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - phase: PropTypes.string.isRequired, - testPlanReportStatuses: PropTypes.arrayOf( - PropTypes.shape({ - at: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }).isRequired, - browser: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }).isRequired, - minimumAtVersion: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }), - exactAtVersion: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }), - testPlanReport: PropTypes.shape({ - id: PropTypes.string.isRequired, - status: PropTypes.string, - runnableTests: PropTypes.arrayOf(PropTypes.object), - finalizedTestResults: PropTypes.arrayOf(PropTypes.object) - }) - }).isRequired - ).isRequired - }).isRequired, + testPlanVersion: TestPlanVersionPropType.isRequired, handleHide: PropTypes.func.isRequired, triggerUpdate: PropTypes.func, show: PropTypes.bool.isRequired diff --git a/client/components/TestPlanReportStatusDialog/queries.js b/client/components/TestPlanReportStatusDialog/queries.js index 75050f8dd..a9940d905 100644 --- a/client/components/TestPlanReportStatusDialog/queries.js +++ b/client/components/TestPlanReportStatusDialog/queries.js @@ -1,84 +1,17 @@ import { gql } from '@apollo/client'; +import { + TEST_PLAN_REPORT_STATUS_FIELDS, + TEST_PLAN_VERSION_FIELDS +} from '@components/common/fragments'; export const TEST_PLAN_REPORT_STATUS_DIALOG_QUERY = gql` + ${TEST_PLAN_REPORT_STATUS_FIELDS('all')} + ${TEST_PLAN_VERSION_FIELDS} query TestPlanReportStatusDialog($testPlanVersionId: ID!) { testPlanVersion(id: $testPlanVersionId) { - id - title - phase - gitSha - gitMessage - updatedAt - draftPhaseReachedAt - candidatePhaseReachedAt - recommendedPhaseTargetDate - recommendedPhaseReachedAt - testPlan { - directory - } + ...TestPlanVersionFields testPlanReportStatuses { - isRequired - at { - id - key - name - atVersions { - id - name - supportedByAutomation - releasedAt - } - } - browser { - id - key - name - } - minimumAtVersion { - id - name - supportedByAutomation - releasedAt - } - exactAtVersion { - id - name - supportedByAutomation - releasedAt - } - testPlanReport { - id - metrics - isFinal - markedFinalAt - issues { - link - isOpen - feedbackType - } - draftTestPlanRuns { - tester { - username - } - testPlanReport { - id - } - testResults { - test { - id - } - atVersion { - id - name - } - browserVersion { - id - name - } - completedAt - } - } - } + ...TestPlanReportStatusFieldsAll } } } diff --git a/client/components/TestPlanVersionsPage/index.jsx b/client/components/TestPlanVersionsPage/index.jsx index bf5b3c71f..0dce14740 100644 --- a/client/components/TestPlanVersionsPage/index.jsx +++ b/client/components/TestPlanVersionsPage/index.jsx @@ -12,7 +12,7 @@ import { } from '../common/ThemeTable'; import VersionString from '../common/VersionString'; import PhasePill from '../common/PhasePill'; -import { convertDateToString } from '../../utils/formatter'; +import { dates } from 'shared'; import { derivePhaseName } from '../../utils/aria'; import styled from '@emotion/styled'; import { @@ -131,7 +131,7 @@ const TestPlanVersionsPage = () => { default: throw new Error('Unexpected case'); } - return convertDateToString(date, 'MMM D, YYYY'); + return dates.convertDateToString(date, 'MMM D, YYYY'); }; const getIconColor = testPlanVersion => { @@ -142,7 +142,7 @@ const TestPlanVersionsPage = () => { }; const getEventDate = testPlanVersion => { - return convertDateToString( + return dates.convertDateToString( (() => { if (testPlanVersion.deprecatedAt) { return testPlanVersion.deprecatedAt; @@ -427,12 +427,14 @@ const TestPlanVersionsPage = () => { {issue.isOpen ? 'Open' : 'Closed'} {issue.at?.name ?? 'AT not specified'} - {convertDateToString(issue.createdAt, 'MMM D, YYYY')} + + {dates.convertDateToString(issue.createdAt, 'MMM D, YYYY')} + {!issue.closedAt ? ( N/A ) : ( - convertDateToString(issue.closedAt, 'MMM D, YYYY') + dates.convertDateToString(issue.closedAt, 'MMM D, YYYY') )} @@ -602,7 +604,9 @@ const TestPlanVersionsPage = () => { return events.map(([phase, date]) => ( - {convertDateToString(date, 'MMM D, YYYY')} + + {dates.convertDateToString(date, 'MMM D, YYYY')} + {getEventBody(phase)} )); diff --git a/client/components/TestPlanVersionsPage/queries.js b/client/components/TestPlanVersionsPage/queries.js index 0fa8d2f57..6a29d10e7 100644 --- a/client/components/TestPlanVersionsPage/queries.js +++ b/client/components/TestPlanVersionsPage/queries.js @@ -1,47 +1,38 @@ import { gql } from '@apollo/client'; +import { + AT_FIELDS, + ISSUE_FIELDS, + TEST_PLAN_FIELDS, + TEST_PLAN_REPORT_FIELDS, + TEST_PLAN_VERSION_FIELDS +} from '@components/common/fragments'; export const TEST_PLAN_VERSIONS_PAGE_QUERY = gql` + ${AT_FIELDS} + ${ISSUE_FIELDS('all')} + ${TEST_PLAN_FIELDS} + ${TEST_PLAN_REPORT_FIELDS} + ${TEST_PLAN_VERSION_FIELDS} query TestPlanVersionsPageQuery($testPlanDirectory: ID!) { ats { - id - name + ...AtFields } testPlan(id: $testPlanDirectory) { - title + ...TestPlanFields issues { - author - title - link - feedbackType - isOpen - createdAt - closedAt + ...IssueFieldsAll at { - name + ...AtFields } } testPlanVersions { - id - testPlan { - directory - } - phase - updatedAt - versionString - deprecatedAt - gitSha - gitMessage - draftPhaseReachedAt - candidatePhaseReachedAt - recommendedPhaseReachedAt + ...TestPlanVersionFields testPlanReports { - id - isFinal + ...TestPlanReportFields at { - name + ...AtFields } } - metadata } } } diff --git a/client/components/TestQueue/Actions.jsx b/client/components/TestQueue/Actions.jsx index c9ba177cc..444e244a6 100644 --- a/client/components/TestQueue/Actions.jsx +++ b/client/components/TestQueue/Actions.jsx @@ -22,6 +22,11 @@ import BasicThemedModal from '../common/BasicThemedModal'; import { evaluateAuth } from '../../utils/evaluateAuth'; import { TEST_PLAN_REPORT_STATUS_DIALOG_QUERY } from '../TestPlanReportStatusDialog/queries'; import ManageBotRunDialogWithButton from '@components/ManageBotRunDialog/WithButton'; +import { + TestPlanPropType, + TestPlanReportPropType, + UserPropType +} from '../common/proptypes'; const ActionContainer = styled.div` display: flex; @@ -296,42 +301,10 @@ const Actions = ({ }; Actions.propTypes = { - me: PropTypes.shape({ - id: PropTypes.string.isRequired, - username: PropTypes.string.isRequired - }), - testPlan: PropTypes.shape({ - directory: PropTypes.string.isRequired - }).isRequired, - testPlanReport: PropTypes.shape({ - id: PropTypes.string.isRequired, - runnableTestsLength: PropTypes.number.isRequired, - conflictsLength: PropTypes.number.isRequired, - draftTestPlanRuns: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - testResultsLength: PropTypes.number.isRequired, - tester: PropTypes.shape({ - id: PropTypes.string.isRequired, - username: PropTypes.string.isRequired, - isBot: PropTypes.bool.isRequired - }) - }) - ).isRequired - }).isRequired, - testers: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - username: PropTypes.string.isRequired, - isBot: PropTypes.bool.isRequired, - ats: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - key: PropTypes.string.isRequired - }) - ) - }) - ).isRequired, + me: UserPropType, + testPlan: TestPlanPropType.isRequired, + testPlanReport: TestPlanReportPropType.isRequired, + testers: PropTypes.arrayOf(UserPropType).isRequired, triggerUpdate: PropTypes.func.isRequired }; diff --git a/client/components/TestQueue/AssignTesters.jsx b/client/components/TestQueue/AssignTesters.jsx index 38f50c076..bd8e40c6f 100644 --- a/client/components/TestQueue/AssignTesters.jsx +++ b/client/components/TestQueue/AssignTesters.jsx @@ -19,6 +19,7 @@ import { } from './queries'; import { SCHEDULE_COLLECTION_JOB_MUTATION } from '../AddTestToQueueWithConfirmation/queries'; import { TEST_PLAN_REPORT_STATUS_DIALOG_QUERY } from '../TestPlanReportStatusDialog/queries'; +import { TestPlanReportPropType, UserPropType } from '../common/proptypes'; const AssignTestersContainer = styled.div` display: flex; @@ -93,7 +94,7 @@ const AssignTesters = ({ me, testers, testPlanReport }) => { const onKeyDown = event => { const { key } = event; - if (key.match(/[0-9a-zA-Z]/)) { + if (key.length === 1 && key.match(/[a-zA-Z0-9]/)) { const container = event.target.closest('[role=menu]'); const matchingMenuItem = Array.from(container.children).find(menuItem => { return menuItem.innerText @@ -328,56 +329,9 @@ const AssignTesters = ({ me, testers, testPlanReport }) => { }; AssignTesters.propTypes = { - me: PropTypes.shape({ - id: PropTypes.string.isRequired - }), - testers: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - username: PropTypes.string.isRequired, - isBot: PropTypes.bool.isRequired, - ats: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - key: PropTypes.string.isRequired - }) - ) - }) - ).isRequired, - testPlanReport: PropTypes.shape({ - id: PropTypes.string.isRequired, - runnableTestsLength: PropTypes.number.isRequired, - draftTestPlanRuns: PropTypes.arrayOf( - PropTypes.shape({ - tester: PropTypes.shape({ id: PropTypes.string.isRequired }).isRequired - }) - ).isRequired, - at: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - key: PropTypes.string.isRequired, - atVersions: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - supportedByAutomation: PropTypes.bool.isRequired - }) - ) - }).isRequired, - browser: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - key: PropTypes.string.isRequired - }).isRequired, - minimumAtVersion: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }), - exactAtVersion: PropTypes.shape({ - id: PropTypes.string.isRequired, - name: PropTypes.string.isRequired - }) - }).isRequired + me: UserPropType, + testers: PropTypes.arrayOf(UserPropType).isRequired, + testPlanReport: TestPlanReportPropType.isRequired }; export default AssignTesters; diff --git a/client/components/TestQueue/CompletionStatusListItem/index.jsx b/client/components/TestQueue/CompletionStatusListItem/index.jsx index 98ed53eaa..2ba2c1818 100644 --- a/client/components/TestQueue/CompletionStatusListItem/index.jsx +++ b/client/components/TestQueue/CompletionStatusListItem/index.jsx @@ -4,6 +4,11 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faRobot } from '@fortawesome/free-solid-svg-icons'; import BotTestCompletionStatus from '@components/TestQueueCompletionStatusListItem/BotTestCompletionStatus'; import PreviouslyAutomatedTestCompletionStatus from '@components/TestQueueCompletionStatusListItem/PreviouslyAutomatedTestCompletionStatus'; +import { + TestPlanReportPropType, + TestPlanRunPropType, + UserPropType +} from '../../common/proptypes'; const CompletionStatusListItem = ({ rowId, @@ -67,20 +72,11 @@ const CompletionStatusListItem = ({ ); }; -// TODO: Update shape for testPlanReport and tester CompletionStatusListItem.propTypes = { rowId: PropTypes.string.isRequired, - testPlanReport: PropTypes.object.isRequired, - testPlanRun: PropTypes.shape({ - id: PropTypes.string.isRequired, - testResultsLength: PropTypes.number.isRequired, - initiatedByAutomation: PropTypes.bool.isRequired, - tester: PropTypes.shape({ - username: PropTypes.string.isRequired, - isBot: PropTypes.bool.isRequired - }).isRequired - }).isRequired, - tester: PropTypes.object.isRequired + testPlanReport: TestPlanReportPropType.isRequired, + testPlanRun: TestPlanRunPropType.isRequired, + tester: UserPropType.isRequired }; export default CompletionStatusListItem; diff --git a/client/components/TestQueue/queries.js b/client/components/TestQueue/queries.js index 6d83dff28..7dd6f7411 100644 --- a/client/components/TestQueue/queries.js +++ b/client/components/TestQueue/queries.js @@ -1,124 +1,89 @@ import { gql } from '@apollo/client'; +import { + AT_FIELDS, + AT_VERSION_FIELDS, + BROWSER_FIELDS, + ME_FIELDS, + TEST_PLAN_FIELDS, + TEST_PLAN_REPORT_FIELDS, + TEST_PLAN_REPORT_STATUS_FIELDS, + TEST_PLAN_RUN_FIELDS, + TEST_PLAN_VERSION_FIELDS, + TEST_RESULT_FIELDS, + USER_FIELDS +} from '@components/common/fragments'; export const TEST_QUEUE_PAGE_QUERY = gql` + ${AT_FIELDS} + ${AT_VERSION_FIELDS} + ${BROWSER_FIELDS} + ${ME_FIELDS} + ${TEST_PLAN_FIELDS} + ${TEST_PLAN_REPORT_FIELDS} + ${TEST_PLAN_REPORT_STATUS_FIELDS()} + ${TEST_PLAN_RUN_FIELDS} + ${TEST_PLAN_VERSION_FIELDS} + ${TEST_RESULT_FIELDS} + ${USER_FIELDS} query TestQueuePage { me { - id - username - roles + ...MeFields } users { - id - username + ...UserFields roles - isBot ats { - id - key + ...AtFields } } ats { - id - key - name + ...AtFields atVersions { - id - name - releasedAt - supportedByAutomation + ...AtVersionFields } browsers { - id - key - name + ...BrowserFields } } testPlans(testPlanVersionPhases: [DRAFT, CANDIDATE, RECOMMENDED]) { - directory - title + ...TestPlanFields testPlanVersions { - id - title - phase - versionString - updatedAt - gitSha - gitMessage + ...TestPlanVersionFields testPlanReports(isFinal: false) { - id + ...TestPlanReportFields at { - id - key - name + ...AtFields atVersions { - id - name - supportedByAutomation - releasedAt + ...AtVersionFields } } browser { - id - key - name + ...BrowserFields } minimumAtVersion { - id - name - supportedByAutomation - releasedAt + ...AtVersionFields } exactAtVersion { - id - name - supportedByAutomation + ...AtVersionFields } - runnableTestsLength - conflictsLength - metrics draftTestPlanRuns { - id + ...TestPlanRunFields testResultsLength - initiatedByAutomation - tester { - id - username - isBot - } testResults { - completedAt + ...TestResultFields } } } testPlanReportStatuses { - testPlanReport { - metrics - draftTestPlanRuns { - testResults { - completedAt - } - } - } + ...TestPlanReportStatusFieldsSimple } } } - testPlanVersions { - id - title - phase - gitSha - gitMessage - testPlan { - directory - } - } - testPlanReports { - id - } } `; export const ASSIGN_TESTER_MUTATION = gql` + ${TEST_PLAN_RUN_FIELDS} mutation AssignTester( $testReportId: ID! $testerId: ID! @@ -128,12 +93,7 @@ export const ASSIGN_TESTER_MUTATION = gql` assignTester(userId: $testerId, testPlanRunId: $testPlanRunId) { testPlanReport { draftTestPlanRuns { - initiatedByAutomation - tester { - id - username - isBot - } + ...TestPlanRunFields } } } @@ -142,18 +102,14 @@ export const ASSIGN_TESTER_MUTATION = gql` `; export const DELETE_TEST_PLAN_RUN = gql` + ${TEST_PLAN_RUN_FIELDS} mutation DeleteTestPlanRun($testReportId: ID!, $testerId: ID!) { testPlanReport(id: $testReportId) { deleteTestPlanRun(userId: $testerId) { testPlanReport { id draftTestPlanRuns { - id - tester { - id - username - isBot - } + ...TestPlanRunFields } } } diff --git a/client/components/TestQueueCompletionStatusListItem/BotTestCompletionStatus/index.js b/client/components/TestQueueCompletionStatusListItem/BotTestCompletionStatus/index.js index 0368b1165..e7e6f7b2e 100644 --- a/client/components/TestQueueCompletionStatusListItem/BotTestCompletionStatus/index.js +++ b/client/components/TestQueueCompletionStatusListItem/BotTestCompletionStatus/index.js @@ -1,6 +1,7 @@ import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import { useTestPlanRunValidatedAssertionCounts } from '../../../hooks/useTestPlanRunValidatedAssertionCounts'; +import { TestPlanRunPropType } from '../../common/proptypes'; const BotTestCompletionStatus = ({ testPlanRun, id, runnableTestsLength }) => { const { @@ -31,22 +32,7 @@ const BotTestCompletionStatus = ({ testPlanRun, id, runnableTestsLength }) => { }; BotTestCompletionStatus.propTypes = { - testPlanRun: PropTypes.shape({ - id: PropTypes.string.isRequired, - testResults: PropTypes.arrayOf( - PropTypes.shape({ - scenarioResults: PropTypes.arrayOf( - PropTypes.shape({ - assertionResults: PropTypes.arrayOf( - PropTypes.shape({ - passed: PropTypes.bool - }) - ) - }) - ) - }) - ) - }).isRequired, + testPlanRun: TestPlanRunPropType.isRequired, id: PropTypes.string.isRequired, runnableTestsLength: PropTypes.number.isRequired }; diff --git a/client/components/TestQueueCompletionStatusListItem/index.js b/client/components/TestQueueCompletionStatusListItem/index.js index 165ad5a47..1da90dfba 100644 --- a/client/components/TestQueueCompletionStatusListItem/index.js +++ b/client/components/TestQueueCompletionStatusListItem/index.js @@ -4,6 +4,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faRobot } from '@fortawesome/free-solid-svg-icons'; import BotTestCompletionStatus from './BotTestCompletionStatus'; import PreviouslyAutomatedTestCompletionStatus from './PreviouslyAutomatedTestCompletionStatus'; +import { TestPlanRunPropType } from '../common/proptypes'; const TestQueueCompletionStatusListItem = ({ runnableTestsLength, @@ -77,15 +78,7 @@ const TestQueueCompletionStatusListItem = ({ TestQueueCompletionStatusListItem.propTypes = { runnableTestsLength: PropTypes.number.isRequired, - testPlanRun: PropTypes.shape({ - id: PropTypes.string.isRequired, - testResultsLength: PropTypes.number.isRequired, - initiatedByAutomation: PropTypes.bool.isRequired, - tester: PropTypes.shape({ - username: PropTypes.string.isRequired, - isBot: PropTypes.bool.isRequired - }).isRequired - }).isRequired, + testPlanRun: TestPlanRunPropType.isRequired, id: PropTypes.string.isRequired }; diff --git a/client/components/TestRenderer/AssertionsFieldset/index.jsx b/client/components/TestRenderer/AssertionsFieldset/index.jsx index 902acc3ff..14db513b0 100644 --- a/client/components/TestRenderer/AssertionsFieldset/index.jsx +++ b/client/components/TestRenderer/AssertionsFieldset/index.jsx @@ -1,11 +1,13 @@ import React, { useMemo } from 'react'; import PropTypes from 'prop-types'; -import { Fieldset } from '..'; import styled from '@emotion/styled'; import supportJson from '../../../resources/support.json'; +import { Fieldset } from '..'; const Label = styled.label` - display: block; + display: inline-block; + margin-bottom: 0.5rem; + margin-right: 0.5rem; input { margin-right: 0.25rem; @@ -28,18 +30,32 @@ const AssertionsFieldset = ({ assertions, commandIndex, assertionsHeader }) => { {assertions.map((assertion, assertionIndex) => { const { description, passed, click } = assertion; - return ( - +

    + {description[0]} + + +
    ); })} diff --git a/client/components/TestRenderer/OutputTextArea/index.jsx b/client/components/TestRenderer/OutputTextArea/index.jsx index 62b173ab3..79dea9570 100644 --- a/client/components/TestRenderer/OutputTextArea/index.jsx +++ b/client/components/TestRenderer/OutputTextArea/index.jsx @@ -4,6 +4,7 @@ import styled from '@emotion/styled'; import { Feedback } from '..'; import { Form } from 'react-bootstrap'; import { NO_OUTPUT_STRING } from './constants'; +import { AtOutputPropType } from '../../common/proptypes'; const OutputTextAreaWrapper = styled.div` > textarea { @@ -85,21 +86,7 @@ const OutputTextArea = ({ OutputTextArea.propTypes = { commandIndex: PropTypes.number.isRequired, - atOutput: PropTypes.shape({ - description: PropTypes.arrayOf( - PropTypes.oneOfType([ - PropTypes.string, - PropTypes.shape({ - required: PropTypes.bool.isRequired, - highlightRequired: PropTypes.bool.isRequired, - description: PropTypes.string.isRequired - }) - ]) - ).isRequired, - value: PropTypes.string.isRequired, - change: PropTypes.func.isRequired, - focus: PropTypes.bool.isRequired - }).isRequired, + atOutput: AtOutputPropType.isRequired, readOnly: PropTypes.bool, isSubmitted: PropTypes.bool.isRequired }; diff --git a/client/components/TestRenderer/index.jsx b/client/components/TestRenderer/index.jsx index aac75c423..b2043a5af 100644 --- a/client/components/TestRenderer/index.jsx +++ b/client/components/TestRenderer/index.jsx @@ -26,6 +26,7 @@ import AssertionsFieldset from './AssertionsFieldset'; import UnexpectedBehaviorsFieldset from './UnexpectedBehaviorsFieldset'; import supportJson from '../../resources/support.json'; import commandsJson from '../../resources/commands.json'; +import { AtPropType, TestResultPropType } from '../common/proptypes/index.js'; const Container = styled.div` width: 100%; @@ -260,9 +261,7 @@ const TestRenderer = ({ let assertionForCommandIndex = commands[i].assertions.findIndex( ({ description }) => description === assertion?.text ); - commands[i].assertions[assertionForCommandIndex].result = passed - ? 'pass' - : 'fail'; + commands[i].assertions[assertionForCommandIndex].result = passed; commands[i].assertions[assertionForCommandIndex].highlightRequired = highlightRequired; } @@ -580,8 +579,8 @@ ErrorComponent.propTypes = { }; TestRenderer.propTypes = { - at: PropTypes.object, - testResult: PropTypes.object, + at: AtPropType, + testResult: TestResultPropType, support: PropTypes.object, testPageUrl: PropTypes.string, testFormatVersion: PropTypes.number, diff --git a/client/components/TestReview/index.jsx b/client/components/TestReview/index.jsx index 783669bbb..78da6bb32 100644 --- a/client/components/TestReview/index.jsx +++ b/client/components/TestReview/index.jsx @@ -9,7 +9,7 @@ import InstructionsRenderer from '../CandidateReview/CandidateTestPlanRun/Instru import FilterButtons from '../common/FilterButtons'; import styled from '@emotion/styled'; import { derivePhaseName } from '../../utils/aria'; -import { convertDateToString } from '../../utils/formatter'; +import { dates } from 'shared'; import supportJson from '../../resources/support.json'; const Ul = styled.ul` @@ -139,7 +139,7 @@ const TestReview = () => { Version History: 
    • - {`R&D completed on ${convertDateToString( + {`R&D completed on ${dates.convertDateToString( testPlanVersion.updatedAt, 'MMM D, YYYY' )}.`} @@ -147,7 +147,7 @@ const TestReview = () => { {!testPlanVersion.draftPhaseReachedAt ? null : (
    • {`ARIA-AT draft review process started on ` + - `${convertDateToString( + `${dates.convertDateToString( testPlanVersion.draftPhaseReachedAt, 'MMM D, YYYY' )} ` + @@ -157,7 +157,7 @@ const TestReview = () => { {!testPlanVersion.candidatePhaseReachedAt ? null : (
    • {`ARIA-AT candidate review process started on ` + - `${convertDateToString( + `${dates.convertDateToString( testPlanVersion.candidatePhaseReachedAt, 'MMM D, YYYY' )} ` + @@ -167,7 +167,7 @@ const TestReview = () => { {!testPlanVersion.recommendedPhaseReachedAt ? null : (
    • {`Version reached ARIA-AT recommended status on ` + - `${convertDateToString( + `${dates.convertDateToString( testPlanVersion.recommendedPhaseReachedAt, 'MMM D, YYYY' )}.`} @@ -176,7 +176,7 @@ const TestReview = () => { {!testPlanVersion.deprecatedAt ? null : (
    • {`Version deprecated on ` + - `${convertDateToString( + `${dates.convertDateToString( testPlanVersion.deprecatedAt, 'MMM D, YYYY' )}.`} diff --git a/client/components/TestReview/queries.js b/client/components/TestReview/queries.js index 4a0b152d3..79f9bf069 100644 --- a/client/components/TestReview/queries.js +++ b/client/components/TestReview/queries.js @@ -1,45 +1,35 @@ import { gql } from '@apollo/client'; +import { + AT_FIELDS, + TEST_PLAN_VERSION_FIELDS +} from '@components/common/fragments'; export const TEST_REVIEW_PAGE_QUERY = gql` + ${AT_FIELDS} + ${TEST_PLAN_VERSION_FIELDS} query TestReviewPageQuery($testPlanVersionId: ID!) { testPlanVersion(id: $testPlanVersionId) { - id - title - versionString - gitSha - gitMessage - testPageUrl - phase - updatedAt - draftPhaseReachedAt - candidatePhaseReachedAt - recommendedPhaseReachedAt - deprecatedAt - testPlan { - directory - } + ...TestPlanVersionFields tests { id - rowNumber title + rowNumber ats { - id - name + ...AtFields } renderedUrls { at { - id + ...AtFields } renderedUrl } renderableContents { at { - id + ...AtFields } renderableContent } } - metadata } } `; diff --git a/client/components/TestRun/CollectionJobContext.js b/client/components/TestRun/CollectionJobContext.js index af16f4f83..2b5b69f9b 100644 --- a/client/components/TestRun/CollectionJobContext.js +++ b/client/components/TestRun/CollectionJobContext.js @@ -3,6 +3,7 @@ import React, { createContext, useState, useEffect } from 'react'; import { useLazyQuery } from '@apollo/client'; import { COLLECTION_JOB_UPDATES_QUERY } from './queries'; import { isJobStatusFinal } from '../../utils/collectionJobStatus'; +import { TestPlanRunPropType } from '../common/proptypes'; const pollInterval = 5000; export const Context = createContext({ @@ -60,12 +61,5 @@ export const Provider = ({ children, testPlanRun }) => { Provider.propTypes = { children: PropTypes.node, - testPlanRun: PropTypes.shape({ - id: PropTypes.string, - collectionJob: PropTypes.shape({ - id: PropTypes.string.isRequired, - status: PropTypes.string.isRequired, - testStatus: PropTypes.arrayOf(PropTypes.object).isRequired - }) - }) + testPlanRun: TestPlanRunPropType }; diff --git a/client/components/TestRun/Heading.js b/client/components/TestRun/Heading.js index cd559be81..f3805bfbd 100644 --- a/client/components/TestRun/Heading.js +++ b/client/components/TestRun/Heading.js @@ -120,13 +120,13 @@ const TestRunHeading = ({
      Test Plan: {testPlanTitle}
      -
      +
      AT: {at} diff --git a/client/components/TestRun/ReviewConflictsModal/index.jsx b/client/components/TestRun/ReviewConflictsModal/index.jsx index 94dcf5b03..40e0ffd59 100644 --- a/client/components/TestRun/ReviewConflictsModal/index.jsx +++ b/client/components/TestRun/ReviewConflictsModal/index.jsx @@ -3,6 +3,11 @@ import PropTypes from 'prop-types'; import { Button, Modal } from 'react-bootstrap'; import styled from '@emotion/styled'; import ReviewConflicts from '../../ReviewConflicts'; +import { + TestPlanReportPropType, + TestPlanVersionPropType, + TestPropType +} from '../../common/proptypes'; const H2 = styled.h2` margin-top: 0; @@ -57,9 +62,9 @@ const ReviewConflictsModal = ({ ReviewConflictsModal.propTypes = { show: PropTypes.bool, - testPlanVersion: PropTypes.object.isRequired, - testPlanReport: PropTypes.object.isRequired, - test: PropTypes.object.isRequired, + testPlanVersion: TestPlanVersionPropType.isRequired, + testPlanReport: TestPlanReportPropType.isRequired, + test: TestPropType.isRequired, handleClose: PropTypes.func, conflictMarkdown: PropTypes.string, issueLink: PropTypes.string.isRequired diff --git a/client/components/TestRun/TestNavigator.jsx b/client/components/TestRun/TestNavigator.jsx index 0fe1fd43c..a803f9c17 100644 --- a/client/components/TestRun/TestNavigator.jsx +++ b/client/components/TestRun/TestNavigator.jsx @@ -60,7 +60,7 @@ const TestNavigator = ({ aria-labelledby="test-navigator-heading" className="test-navigator-list" > - {tests.map(test => { + {tests.map((test, index) => { let resultClassName = 'not-started'; let resultStatus = 'Not Started'; @@ -126,8 +126,11 @@ const TestNavigator = ({ key={`TestNavigatorItem_${test.id}`} > await handleTestClick(test.index)} + onClick={async e => { + e.preventDefault(); + await handleTestClick(test.index); + }} + href={`#${index + 1}`} className="test-name" aria-current={test.index === currentTestIndex} > diff --git a/client/components/TestRun/index.jsx b/client/components/TestRun/index.jsx index 27a7ce149..c08ecb96d 100644 --- a/client/components/TestRun/index.jsx +++ b/client/components/TestRun/index.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { Helmet } from 'react-helmet'; import { Link, useNavigate, useParams } from 'react-router-dom'; import useRouterQuery from '../../hooks/useRouterQuery'; @@ -39,8 +39,9 @@ import { evaluateAuth } from '../../utils/evaluateAuth'; import './TestRun.css'; import ReviewConflicts from '../ReviewConflicts'; import createIssueLink from '../../utils/createIssueLink'; -import { convertDateToString } from '../../utils/formatter'; +import { dates } from 'shared'; import { Provider as CollectionJobContextProvider } from './CollectionJobContext'; +import { useUrlTestIndex } from '../../hooks/useUrlTestIndex'; const TestRun = () => { const params = useParams(); @@ -119,7 +120,7 @@ const TestRun = () => { const [testPlanReport, setTestPlanReport] = useState({}); const [testPlanVersion, setTestPlanVersion] = useState(); const [currentTest, setCurrentTest] = useState({}); - const [currentTestIndex, setCurrentTestIndex] = useState(0); + const [currentTestIndex, setCurrentTestIndex] = useUrlTestIndex(tests.length); const [currentTestAtVersionId, setCurrentTestAtVersionId] = useState(''); const [currentTestBrowserVersionId, setCurrentTestBrowserVersionId] = useState(''); @@ -144,6 +145,22 @@ const TestRun = () => { const isAdminReviewer = !!(isAdmin && openAsUserId); const openAsUser = users?.find(user => user.id === openAsUserId); + // Define createTestResultForRenderer as a memoized function + const createTestResultForRenderer = useCallback( + async (testId, atVersionId, browserVersionId) => { + const result = await createTestResult({ + variables: { + testPlanRunId, + testId, + atVersionId, + browserVersionId + } + }); + return result.data.testPlanRun.findOrCreateTestResult; + }, + [createTestResult, testPlanRunId] + ); + useEffect(() => { reset(); @@ -153,13 +170,14 @@ const TestRun = () => { setPageReady(false); if (isSignedIn) { (async () => { - const { testPlanRun, testPlanReport } = + const { testPlanRun: updatedTestPlanRun } = await createTestResultForRenderer( currentTest.id, currentTestAtVersionId, currentTestBrowserVersionId ); - updateLocalState(testPlanRun, testPlanReport); + const { testPlanReport: updatedTestPlanReport } = updatedTestPlanRun; + updateLocalState(updatedTestPlanRun, updatedTestPlanReport); setPageReady(true); })(); } else { @@ -168,7 +186,7 @@ const TestRun = () => { setPageReady(true); } } else if (data) setup(data); - }, [currentTestIndex]); + }, [currentTestIndex, createTestResultForRenderer]); const setup = data => { const { testPlanRun, users } = data; @@ -312,22 +330,6 @@ const TestRun = () => { const toggleTestNavigator = () => setShowTestNavigator(!showTestNavigator); - const createTestResultForRenderer = async ( - testId, - atVersionId, - browserVersionId - ) => { - const result = await createTestResult({ - variables: { - testPlanRunId, - testId, - atVersionId, - browserVersionId - } - }); - return result.data.testPlanRun.findOrCreateTestResult; - }; - // Check to see if there are tests to run const testCount = tests.length; @@ -353,7 +355,7 @@ const TestRun = () => { issueLink = createIssueLink({ testPlanTitle: testPlanVersion.title, testPlanDirectory: testPlanVersion.testPlan.directory, - versionString: `V${convertDateToString( + versionString: `V${dates.convertDateToString( testPlanVersion.updatedAt, 'YY.MM.DD' )}`, @@ -414,7 +416,7 @@ const TestRun = () => { ...scenarioResult.assertionResults.find( ({ assertion: { text } }) => text === description ), - passed: result === 'pass' + passed: result }; assertionResults.push( captureHighlightRequired @@ -605,12 +607,14 @@ const TestRun = () => { reset(); setPageReady(false); - const { testPlanRun, testPlanReport } = await createTestResultForRenderer( - currentTest.id, - currentTestAtVersionId, - currentTestBrowserVersionId - ); - updateLocalState(testPlanRun, testPlanReport); + const { testPlanRun: updatedTestPlanRun } = + await createTestResultForRenderer( + currentTest.id, + currentTestAtVersionId, + currentTestBrowserVersionId + ); + const { testPlanReport: updatedTestPlanReport } = updatedTestPlanRun; + updateLocalState(updatedTestPlanRun, updatedTestPlanReport); setPageReady(true); // close modal after action @@ -681,14 +685,16 @@ const TestRun = () => { if (isSubmit) { const result = await submitTestResult({ variables }); - const { testPlanRun, testPlanReport } = + const { testPlanRun: updatedTestPlanRun } = result.data.testResult.submitTestResult; - updateLocalState(testPlanRun, testPlanReport); + const { testPlanReport: updatedTestPlanReport } = updatedTestPlanRun; + updateLocalState(updatedTestPlanRun, updatedTestPlanReport); } else { const result = await saveTestResult({ variables }); - const { testPlanRun, testPlanReport } = + const { testPlanRun: updatedTestPlanRun } = result.data.testResult.saveTestResult; - updateLocalState(testPlanRun, testPlanReport); + const { testPlanReport: updatedTestPlanReport } = updatedTestPlanRun; + updateLocalState(updatedTestPlanRun, updatedTestPlanReport); } }; @@ -850,13 +856,14 @@ const TestRun = () => { setCurrentBrowserVersion(browserVersion); setUpdateMessageComponent(updateMessageComponent); - const { testPlanRun: _testPlanRun, testPlanReport: _testPlanReport } = + const { testPlanRun: updatedTestPlanRun } = await createTestResultForRenderer( currentTest.id, atVersion.id, browserVersion.id ); - updateLocalState(_testPlanRun, _testPlanReport); + const { testPlanReport: updatedTestPlanReport } = updatedTestPlanRun; + updateLocalState(updatedTestPlanRun, updatedTestPlanReport); handleAtAndBrowserDetailsModalCloseAction(); }; @@ -992,7 +999,7 @@ const TestRun = () => { return ( <> -

      +

      Test {currentTest.seq}: {currentTest.title}

      diff --git a/client/components/TestRun/queries.js b/client/components/TestRun/queries.js index 1499f6f87..65bbb9cf3 100644 --- a/client/components/TestRun/queries.js +++ b/client/components/TestRun/queries.js @@ -1,331 +1,158 @@ import { gql } from '@apollo/client'; +import { + AT_FIELDS, + AT_VERSION_FIELDS, + BROWSER_FIELDS, + BROWSER_VERSION_FIELDS, + COLLECTION_JOB_FIELDS, + ME_FIELDS, + SCENARIO_RESULT_FIELDS, + TEST_FIELDS, + TEST_PLAN_REPORT_CONFLICT_FIELDS, + TEST_PLAN_VERSION_FIELDS, + TEST_RESULT_FIELDS, + USER_FIELDS +} from '@components/common/fragments'; export const TEST_RUN_PAGE_QUERY = gql` + ${AT_FIELDS} + ${AT_VERSION_FIELDS} + ${BROWSER_FIELDS} + ${BROWSER_VERSION_FIELDS} + ${COLLECTION_JOB_FIELDS} + ${ME_FIELDS} + ${SCENARIO_RESULT_FIELDS('all')} + ${TEST_FIELDS()} + ${TEST_FIELDS('all')} + ${TEST_PLAN_REPORT_CONFLICT_FIELDS} + ${TEST_PLAN_VERSION_FIELDS} + ${TEST_RESULT_FIELDS} + ${USER_FIELDS} query TestPlanRunPage($testPlanRunId: ID!) { testPlanRun(id: $testPlanRunId) { id initiatedByAutomation collectionJob { - id - status - externalLogsUrl - testStatus { - test { - id - } - status - } + ...CollectionJobFields } tester { - id - username - isBot + ...UserFields } testResults { - id - startedAt - completedAt + ...TestResultFields test { - id - rowNumber - title - renderedUrl + ...TestFieldsSimple renderableContent } scenarioResults { - id - scenario { - commands { - id - text - } - } - output - assertionResults { - id - assertion { - text - phrase - } - passed - } - mustAssertionResults: assertionResults(priority: MUST) { - assertion { - text - phrase - } - passed - } - shouldAssertionResults: assertionResults(priority: SHOULD) { - assertion { - text - phrase - } - passed - } - mayAssertionResults: assertionResults(priority: MAY) { - assertion { - text - phrase - } - passed - } - unexpectedBehaviors { - id - text - impact - details - } + ...ScenarioResultFieldsAll } atVersion { - id - name + ...AtVersionFields } browserVersion { - id - name + ...BrowserVersionFields } } testPlanReport { id conflicts { - source { - test { - id - title - rowNumber - } - scenario { - id - commands { - text - } - } - assertion { - id - text - phrase - } - } - conflictingResults { - testPlanRun { - id - tester { - username - } - } - scenarioResult { - output - unexpectedBehaviors { - text - impact - details - } - } - assertionResult { - passed - } - } + ...TestPlanReportConflictFields } at { - id - name + ...AtFields atVersions { - id - name - releasedAt + ...AtVersionFields } } minimumAtVersion { - id - name - releasedAt + ...AtVersionFields } exactAtVersion { - id - name + ...AtVersionFields } browser { - id - name + ...BrowserFields browserVersions { - id - name + ...BrowserVersionFields } } testPlanVersion { - id - title - phase - updatedAt - gitSha - testPageUrl - testPlan { - directory - } - metadata + ...TestPlanVersionFields } runnableTests { - id - rowNumber - title - ats { - id - name - } - renderedUrl - scenarios { - id - at { - id - name - } - commands { - id - text - } - } - assertions { - id - priority - text - } + ...TestFieldsAll } } } me { - id - username - roles + ...MeFields } users { - id - username - isBot + ...UserFields } } `; export const COLLECTION_JOB_UPDATES_QUERY = gql` + ${COLLECTION_JOB_FIELDS} query CollectionJob($collectionJobId: ID!) { collectionJob(id: $collectionJobId) { - id - status - externalLogsUrl - testStatus { - test { - id - } - status - } + ...CollectionJobFields } } `; export const TEST_RUN_PAGE_ANON_QUERY = gql` + ${AT_FIELDS} + ${AT_VERSION_FIELDS} + ${BROWSER_FIELDS} + ${BROWSER_VERSION_FIELDS} + ${TEST_FIELDS('all')} + ${TEST_PLAN_REPORT_CONFLICT_FIELDS} + ${TEST_PLAN_VERSION_FIELDS} query TestPlanRunAnonPage($testPlanReportId: ID!) { testPlanReport(id: $testPlanReportId) { id conflicts { - source { - test { - id - title - rowNumber - } - scenario { - id - commands { - text - } - } - assertion { - id - text - phrase - } - } - conflictingResults { - testPlanRun { - id - tester { - username - isBot - } - } - scenarioResult { - output - unexpectedBehaviors { - text - impact - details - } - } - assertionResult { - passed - } - } + ...TestPlanReportConflictFields } at { - id - name + ...AtFields atVersions { - id - name + ...AtVersionFields } } browser { - id - name + ...BrowserFields browserVersions { - id - name + ...BrowserVersionFields } } testPlanVersion { - id - title - phase - updatedAt - gitSha - testPageUrl - testPlan { - directory - } - metadata + ...TestPlanVersionFields } runnableTests { - id - rowNumber - title - ats { - id - name - } - renderedUrl + ...TestFieldsAll renderableContent - scenarios { - id - at { - id - name - } - commands { - id - text - } - } - assertions { - id - priority - text - } } } } `; export const FIND_OR_CREATE_TEST_RESULT_MUTATION = gql` + ${AT_FIELDS} + ${AT_VERSION_FIELDS} + ${BROWSER_FIELDS} + ${BROWSER_VERSION_FIELDS} + ${COLLECTION_JOB_FIELDS} + ${SCENARIO_RESULT_FIELDS('all')} + ${TEST_FIELDS()} + ${TEST_FIELDS('all')} + ${TEST_PLAN_REPORT_CONFLICT_FIELDS} + ${TEST_PLAN_VERSION_FIELDS} + ${TEST_RESULT_FIELDS} + ${USER_FIELDS} mutation FindOrCreateTestResult( $testPlanRunId: ID! $testId: ID! @@ -341,287 +168,57 @@ export const FIND_OR_CREATE_TEST_RESULT_MUTATION = gql` locationOfData testPlanRun { id + initiatedByAutomation + collectionJob { + ...CollectionJobFields + } tester { - id - username - isBot + ...UserFields } testResults { - id - startedAt - completedAt + ...TestResultFields test { - id - rowNumber - title - renderedUrl + ...TestFieldsSimple renderableContent } scenarioResults { - id - scenario { - commands { - id - text - } - } - output - assertionResults { - id - assertion { - text - phrase - } - passed - } - mustAssertionResults: assertionResults(priority: MUST) { - assertion { - text - phrase - } - passed - } - shouldAssertionResults: assertionResults(priority: SHOULD) { - assertion { - text - phrase - } - passed - } - mayAssertionResults: assertionResults(priority: MAY) { - assertion { - text - phrase - } - passed - } - unexpectedBehaviors { - id - text - impact - details - } + ...ScenarioResultFieldsAll } atVersion { - id - name + ...AtVersionFields } browserVersion { - id - name + ...BrowserVersionFields } } testPlanReport { id conflicts { - source { - test { - id - title - rowNumber - } - scenario { - id - commands { - text - } - } - assertion { - id - text - phrase - } - } - conflictingResults { - testPlanRun { - id - tester { - username - } - } - scenarioResult { - output - unexpectedBehaviors { - text - impact - details - } - } - assertionResult { - passed - } - } + ...TestPlanReportConflictFields } at { - id - name + ...AtFields atVersions { - id - name - releasedAt + ...AtVersionFields } } minimumAtVersion { - id - name - releasedAt + ...AtVersionFields } exactAtVersion { - id - name + ...AtVersionFields } browser { - id - name + ...BrowserFields browserVersions { - id - name + ...BrowserVersionFields } } testPlanVersion { - id - title - phase - updatedAt - gitSha - testPageUrl - testPlan { - directory - } - metadata + ...TestPlanVersionFields } runnableTests { - id - rowNumber - title - ats { - id - name - } - renderedUrl - scenarios { - id - at { - id - name - } - commands { - id - text - } - } - assertions { - id - priority - text - } - } - } - } - testPlanReport { - id - conflicts { - source { - test { - id - title - rowNumber - } - scenario { - id - commands { - text - } - } - assertion { - id - text - phrase - } - } - conflictingResults { - testPlanRun { - id - tester { - isBot - username - } - } - scenarioResult { - output - unexpectedBehaviors { - text - impact - details - } - } - assertionResult { - passed - } - } - } - at { - id - name - atVersions { - id - name - releasedAt - } - } - minimumAtVersion { - id - name - releasedAt - } - exactAtVersion { - id - name - } - browser { - id - name - browserVersions { - id - name - } - } - testPlanVersion { - id - title - phase - updatedAt - gitSha - testPageUrl - testPlan { - directory - } - metadata - } - runnableTests { - id - rowNumber - title - ats { - id - name - } - renderedUrl - scenarios { - id - at { - id - name - } - commands { - id - text - } - } - assertions { - id - priority - text + ...TestFieldsAll } } } @@ -631,6 +228,18 @@ export const FIND_OR_CREATE_TEST_RESULT_MUTATION = gql` `; export const SAVE_TEST_RESULT_MUTATION = gql` + ${AT_FIELDS} + ${AT_VERSION_FIELDS} + ${BROWSER_FIELDS} + ${BROWSER_VERSION_FIELDS} + ${COLLECTION_JOB_FIELDS} + ${SCENARIO_RESULT_FIELDS('all')} + ${TEST_FIELDS()} + ${TEST_FIELDS('all')} + ${TEST_PLAN_REPORT_CONFLICT_FIELDS} + ${TEST_PLAN_VERSION_FIELDS} + ${TEST_RESULT_FIELDS} + ${USER_FIELDS} mutation SaveTestResult( $id: ID! $atVersionId: ID! @@ -649,286 +258,57 @@ export const SAVE_TEST_RESULT_MUTATION = gql` locationOfData testPlanRun { id + initiatedByAutomation + collectionJob { + ...CollectionJobFields + } tester { - id - username - isBot + ...UserFields } testResults { - id - startedAt - completedAt + ...TestResultFields test { - id - rowNumber - title - renderedUrl + ...TestFieldsSimple renderableContent } scenarioResults { - id - scenario { - commands { - id - text - } - } - output - assertionResults { - id - assertion { - text - phrase - } - passed - } - mustAssertionResults: assertionResults(priority: MUST) { - assertion { - text - phrase - } - passed - } - shouldAssertionResults: assertionResults(priority: SHOULD) { - assertion { - text - phrase - } - passed - } - mayAssertionResults: assertionResults(priority: MAY) { - assertion { - text - phrase - } - passed - } - unexpectedBehaviors { - id - text - impact - details - } + ...ScenarioResultFieldsAll } atVersion { - id - name + ...AtVersionFields } browserVersion { - id - name + ...BrowserVersionFields } } testPlanReport { id conflicts { - source { - test { - id - title - rowNumber - } - scenario { - id - commands { - text - } - } - assertion { - id - text - phrase - } - } - conflictingResults { - testPlanRun { - id - tester { - username - } - } - scenarioResult { - output - unexpectedBehaviors { - text - impact - details - } - } - assertionResult { - passed - } - } + ...TestPlanReportConflictFields } at { - id - name + ...AtFields atVersions { - id - name - releasedAt + ...AtVersionFields } } minimumAtVersion { - id - name - releasedAt + ...AtVersionFields } exactAtVersion { - id - name + ...AtVersionFields } browser { - id - name + ...BrowserFields browserVersions { - id - name + ...BrowserVersionFields } } testPlanVersion { - id - title - phase - updatedAt - gitSha - testPageUrl - testPlan { - directory - } - metadata + ...TestPlanVersionFields } runnableTests { - id - rowNumber - title - ats { - id - name - } - renderedUrl - scenarios { - id - at { - id - name - } - commands { - id - text - } - } - assertions { - id - priority - text - } - } - } - } - testPlanReport { - id - conflicts { - source { - test { - id - title - rowNumber - } - scenario { - id - commands { - text - } - } - assertion { - id - text - phrase - } - } - conflictingResults { - testPlanRun { - id - tester { - username - } - } - scenarioResult { - output - unexpectedBehaviors { - text - impact - details - } - } - assertionResult { - passed - } - } - } - at { - id - name - atVersions { - id - name - releasedAt - } - } - minimumAtVersion { - id - name - releasedAt - } - exactAtVersion { - id - name - } - browser { - id - name - browserVersions { - id - name - } - } - testPlanVersion { - id - title - phase - updatedAt - gitSha - testPageUrl - testPlan { - directory - } - metadata - } - runnableTests { - id - rowNumber - title - ats { - id - name - } - renderedUrl - scenarios { - id - at { - id - name - } - commands { - id - text - } - } - assertions { - id - priority - text + ...TestFieldsAll } } } @@ -938,6 +318,18 @@ export const SAVE_TEST_RESULT_MUTATION = gql` `; export const SUBMIT_TEST_RESULT_MUTATION = gql` + ${AT_FIELDS} + ${AT_VERSION_FIELDS} + ${BROWSER_FIELDS} + ${BROWSER_VERSION_FIELDS} + ${COLLECTION_JOB_FIELDS} + ${SCENARIO_RESULT_FIELDS('all')} + ${TEST_FIELDS()} + ${TEST_FIELDS('all')} + ${TEST_PLAN_REPORT_CONFLICT_FIELDS} + ${TEST_PLAN_VERSION_FIELDS} + ${TEST_RESULT_FIELDS} + ${USER_FIELDS} mutation SubmitTestResult( $id: ID! $atVersionId: ID! @@ -956,285 +348,57 @@ export const SUBMIT_TEST_RESULT_MUTATION = gql` locationOfData testPlanRun { id + initiatedByAutomation + collectionJob { + ...CollectionJobFields + } tester { - id - username + ...UserFields } testResults { - id - startedAt - completedAt + ...TestResultFields test { - id - rowNumber - title - renderedUrl + ...TestFieldsSimple renderableContent } scenarioResults { - id - scenario { - commands { - id - text - } - } - output - assertionResults { - id - assertion { - text - phrase - } - passed - } - mustAssertionResults: assertionResults(priority: MUST) { - assertion { - text - phrase - } - passed - } - shouldAssertionResults: assertionResults(priority: SHOULD) { - assertion { - text - phrase - } - passed - } - mayAssertionResults: assertionResults(priority: MAY) { - assertion { - text - phrase - } - passed - } - unexpectedBehaviors { - id - text - impact - details - } + ...ScenarioResultFieldsAll } atVersion { - id - name + ...AtVersionFields } browserVersion { - id - name + ...BrowserVersionFields } } testPlanReport { id conflicts { - source { - test { - id - title - rowNumber - } - scenario { - id - commands { - text - } - } - assertion { - id - text - phrase - } - } - conflictingResults { - testPlanRun { - id - tester { - username - } - } - scenarioResult { - output - unexpectedBehaviors { - text - impact - details - } - } - assertionResult { - passed - } - } + ...TestPlanReportConflictFields } at { - id - name + ...AtFields atVersions { - id - name - releasedAt + ...AtVersionFields } } minimumAtVersion { - id - name - releasedAt + ...AtVersionFields } exactAtVersion { - id - name + ...AtVersionFields } browser { - id - name + ...BrowserFields browserVersions { - id - name + ...BrowserVersionFields } } testPlanVersion { - id - title - phase - updatedAt - gitSha - testPageUrl - testPlan { - directory - } - metadata + ...TestPlanVersionFields } runnableTests { - id - rowNumber - title - ats { - id - name - } - renderedUrl - scenarios { - id - at { - id - name - } - commands { - id - text - } - } - assertions { - id - priority - text - } - } - } - } - testPlanReport { - id - conflicts { - source { - test { - id - title - rowNumber - } - scenario { - id - commands { - text - } - } - assertion { - id - text - phrase - } - } - conflictingResults { - testPlanRun { - id - tester { - username - } - } - scenarioResult { - output - unexpectedBehaviors { - text - impact - details - } - } - assertionResult { - passed - } - } - } - at { - id - name - atVersions { - id - name - releasedAt - } - } - minimumAtVersion { - id - name - releasedAt - } - exactAtVersion { - id - name - } - browser { - id - name - browserVersions { - id - name - } - } - testPlanVersion { - id - title - phase - updatedAt - gitSha - testPageUrl - testPlan { - directory - } - metadata - } - runnableTests { - id - rowNumber - title - ats { - id - name - } - renderedUrl - scenarios { - id - at { - id - name - } - commands { - id - text - } - } - assertions { - id - priority - text + ...TestFieldsAll } } } @@ -1254,14 +418,14 @@ export const DELETE_TEST_RESULT_MUTATION = gql` `; export const FIND_OR_CREATE_BROWSER_VERSION_MUTATION = gql` + ${BROWSER_VERSION_FIELDS} mutation FindOrCreateBrowserVersion( $browserId: ID! $browserVersionName: String! ) { browser(id: $browserId) { findOrCreateBrowserVersion(input: { name: $browserVersionName }) { - id - name + ...BrowserVersionFields } } } diff --git a/client/components/UserSettings/UserSettings.jsx b/client/components/UserSettings/UserSettings.jsx index 3a8f99d22..958d27f79 100644 --- a/client/components/UserSettings/UserSettings.jsx +++ b/client/components/UserSettings/UserSettings.jsx @@ -67,12 +67,12 @@ const UserSettings = () => { return ( - + Settings | ARIA-AT

      Settings

      -
      +

      User Details

      {

      - Submit the form below to update the assistive technologies you can - test: + Update the assistive technologies you can test by selecting from the + options below:

      -

      ATs

      +

      Assistive Technologies

      {['Select a Version', ...atVersions].map(item => (
      + {tester.username} + + {' '} + on{' '} + {dates.convertDateToString( + testResult.completedAt, + 'MMMM DD, YYYY' + )} + . + + ); + } + } + } + return l; + }, [testPlanReports, testId]); + + if (lines.length === 0) { + return null; + } + + return ( +
        + {lines} +
      + ); +}; + +RunHistory.propTypes = { + testPlanReports: PropTypes.arrayOf(TestPlanReportPropType), + testId: PropTypes.string +}; + +export default RunHistory; diff --git a/client/components/common/TestPlanResultsTable/index.jsx b/client/components/common/TestPlanResultsTable/index.jsx index c29bcb688..1cd97a814 100644 --- a/client/components/common/TestPlanResultsTable/index.jsx +++ b/client/components/common/TestPlanResultsTable/index.jsx @@ -4,6 +4,7 @@ import { Table } from 'react-bootstrap'; import nextId from 'react-id-generator'; import { getMetrics } from 'shared'; import './TestPlanResultsTable.css'; +import { TestPropType, TestResultPropType } from '../proptypes'; const getAssertionResultText = (passed, priority) => { if (priority === 'MAY') { @@ -191,15 +192,8 @@ const TestPlanResultsTable = ({ }; TestPlanResultsTable.propTypes = { - test: PropTypes.shape({ - title: PropTypes.string.isRequired, - at: PropTypes.shape({ - name: PropTypes.string.isRequired - }).isRequired - }), - testResult: PropTypes.shape({ - scenarioResults: PropTypes.array.isRequired - }), + test: TestPropType.isRequired, + testResult: TestResultPropType.isRequired, tableClassName: PropTypes.string, optionalHeader: PropTypes.node, commandHeadingLevel: PropTypes.number diff --git a/client/components/common/UpdateTargetDateModal/index.jsx b/client/components/common/UpdateTargetDateModal/index.jsx index 17bc30929..c9182cd54 100644 --- a/client/components/common/UpdateTargetDateModal/index.jsx +++ b/client/components/common/UpdateTargetDateModal/index.jsx @@ -2,8 +2,8 @@ import React, { useEffect, useState, useRef } from 'react'; import PropTypes from 'prop-types'; import { Form } from 'react-bootstrap'; import styled from '@emotion/styled'; +import { dates } from 'shared'; import BasicModal from '../BasicModal'; -import { convertDateToString, isValidDate } from '../../../utils/formatter'; const ModalInnerSectionContainer = styled.div` display: flex; @@ -20,12 +20,12 @@ const UpdateTargetDateModal = ({ const dateTextRef = useRef(); const [updatedDateText, setUpdatedDateText] = useState( - convertDateToString(dateText) + dates.convertDateToString(dateText) ); const [isDateError, setIsDateError] = useState(false); useEffect(() => { - setUpdatedDateText(convertDateToString(dateText)); + setUpdatedDateText(dates.convertDateToString(dateText)); }, [dateText]); const handleDateTextChange = e => { @@ -73,7 +73,7 @@ const UpdateTargetDateModal = ({ const dateTextError = !updatedDateText || updatedDateText.length !== 10 || - !isValidDate(updatedDateText); + !dates.isValidDate(updatedDateText); if (dateTextError) { setIsDateError(dateTextError); diff --git a/client/components/common/UpdateVersionModal/index.jsx b/client/components/common/UpdateVersionModal/index.jsx index 83a5daad9..42916c2eb 100644 --- a/client/components/common/UpdateVersionModal/index.jsx +++ b/client/components/common/UpdateVersionModal/index.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { Form } from 'react-bootstrap'; import styled from '@emotion/styled'; import BasicModal from '../BasicModal'; -import { convertDateToString, isValidDate } from '../../../utils/formatter'; +import { dates } from 'shared'; const ModalInnerSectionContainer = styled.div` display: flex; @@ -24,13 +24,15 @@ const UpdateVersionModal = ({ const [updatedVersionText, setUpdatedVersionText] = useState(versionText); const [updatedDateAvailabilityText, setUpdatedDateAvailabilityText] = - useState(convertDateToString(dateAvailabilityText)); + useState(dates.convertDateToString(dateAvailabilityText)); const [isVersionError, setIsVersionError] = useState(false); const [isDateError, setIsDateError] = useState(false); useEffect(() => { setUpdatedVersionText(versionText); - setUpdatedDateAvailabilityText(convertDateToString(dateAvailabilityText)); + setUpdatedDateAvailabilityText( + dates.convertDateToString(dateAvailabilityText) + ); }, [versionText, dateAvailabilityText]); const handleVersionTextChange = e => { @@ -85,7 +87,7 @@ const UpdateVersionModal = ({ const dateTextError = !updatedDateAvailabilityText || updatedDateAvailabilityText.length !== 10 || - !isValidDate(updatedDateAvailabilityText); + !dates.isValidDate(updatedDateAvailabilityText); if (versionTextError || dateTextError) { setIsVersionError(versionTextError); diff --git a/client/components/common/fragments/AssertionResult.js b/client/components/common/fragments/AssertionResult.js new file mode 100644 index 000000000..abf061364 --- /dev/null +++ b/client/components/common/fragments/AssertionResult.js @@ -0,0 +1,17 @@ +import { gql } from '@apollo/client'; + +const ASSERTION_RESULT_FIELDS = gql` + fragment AssertionResultFields on AssertionResult { + __typename + id + passed + assertion { + id + text + phrase + priority + } + } +`; + +export default ASSERTION_RESULT_FIELDS; diff --git a/client/components/common/fragments/At.js b/client/components/common/fragments/At.js new file mode 100644 index 000000000..a9ff391a8 --- /dev/null +++ b/client/components/common/fragments/At.js @@ -0,0 +1,12 @@ +import { gql } from '@apollo/client'; + +const AT_FIELDS = gql` + fragment AtFields on At { + __typename + id + key + name + } +`; + +export default AT_FIELDS; diff --git a/client/components/common/fragments/AtVersion.js b/client/components/common/fragments/AtVersion.js new file mode 100644 index 000000000..aba85e9cb --- /dev/null +++ b/client/components/common/fragments/AtVersion.js @@ -0,0 +1,13 @@ +import { gql } from '@apollo/client'; + +const AT_VERSION_FIELDS = gql` + fragment AtVersionFields on AtVersion { + __typename + id + name + releasedAt + supportedByAutomation + } +`; + +export default AT_VERSION_FIELDS; diff --git a/client/components/common/fragments/Browser.js b/client/components/common/fragments/Browser.js new file mode 100644 index 000000000..6b86b950c --- /dev/null +++ b/client/components/common/fragments/Browser.js @@ -0,0 +1,12 @@ +import { gql } from '@apollo/client'; + +const BROWSER_FIELDS = gql` + fragment BrowserFields on Browser { + __typename + id + key + name + } +`; + +export default BROWSER_FIELDS; diff --git a/client/components/common/fragments/BrowserVersion.js b/client/components/common/fragments/BrowserVersion.js new file mode 100644 index 000000000..a4a9e9ce2 --- /dev/null +++ b/client/components/common/fragments/BrowserVersion.js @@ -0,0 +1,11 @@ +import { gql } from '@apollo/client'; + +const BROWSER_VERSION_FIELDS = gql` + fragment BrowserVersionFields on BrowserVersion { + __typename + id + name + } +`; + +export default BROWSER_VERSION_FIELDS; diff --git a/client/components/common/fragments/CollectionJob.js b/client/components/common/fragments/CollectionJob.js new file mode 100644 index 000000000..bf9af39ef --- /dev/null +++ b/client/components/common/fragments/CollectionJob.js @@ -0,0 +1,18 @@ +import { gql } from '@apollo/client'; + +const COLLECTION_JOB_FIELDS = gql` + fragment CollectionJobFields on CollectionJob { + __typename + id + status + externalLogsUrl + testStatus { + test { + id + } + status + } + } +`; + +export default COLLECTION_JOB_FIELDS; diff --git a/client/components/common/fragments/Issue.js b/client/components/common/fragments/Issue.js new file mode 100644 index 000000000..629e7f506 --- /dev/null +++ b/client/components/common/fragments/Issue.js @@ -0,0 +1,38 @@ +import { gql } from '@apollo/client'; + +/** + * + * @param {'simple'|'all'} type + * @returns {*} + */ +const ISSUE_FIELDS = (type = 'simple') => { + switch (type) { + case 'simple': + return gql` + fragment IssueFieldsSimple on Issue { + __typename + link + isOpen + feedbackType + isCandidateReview + } + `; + case 'all': + return gql` + fragment IssueFieldsAll on Issue { + __typename + link + title + author + isOpen + feedbackType + isCandidateReview + testNumberFilteredByAt + createdAt + closedAt + } + `; + } +}; + +export default ISSUE_FIELDS; diff --git a/client/components/common/fragments/Me.js b/client/components/common/fragments/Me.js new file mode 100644 index 000000000..128e7072d --- /dev/null +++ b/client/components/common/fragments/Me.js @@ -0,0 +1,12 @@ +import { gql } from '@apollo/client'; + +const ME_FIELDS = gql` + fragment MeFields on User { + __typename + id + username + roles + } +`; + +export default ME_FIELDS; diff --git a/client/components/common/fragments/ScenarioResult.js b/client/components/common/fragments/ScenarioResult.js new file mode 100644 index 000000000..2c049a87f --- /dev/null +++ b/client/components/common/fragments/ScenarioResult.js @@ -0,0 +1,61 @@ +import { gql } from '@apollo/client'; +import { ASSERTION_RESULT_FIELDS } from '@components/common/fragments/index'; + +/** + * @param {'simple'|'all'} type + * @returns {*} + */ +const SCENARIO_RESULT_FIELDS = (type = 'simple') => { + switch (type) { + case 'simple': + return gql` + fragment ScenarioResultFieldsSimple on ScenarioResult { + __typename + id + scenario { + commands { + id + text + atOperatingMode + } + } + } + `; + case 'all': + return gql` + ${ASSERTION_RESULT_FIELDS} + fragment ScenarioResultFieldsAll on ScenarioResult { + __typename + id + output + scenario { + commands { + id + text + atOperatingMode + } + } + assertionResults { + ...AssertionResultFields + } + mustAssertionResults: assertionResults(priority: MUST) { + ...AssertionResultFields + } + shouldAssertionResults: assertionResults(priority: SHOULD) { + ...AssertionResultFields + } + mayAssertionResults: assertionResults(priority: MAY) { + ...AssertionResultFields + } + unexpectedBehaviors { + id + text + impact + details + } + } + `; + } +}; + +export default SCENARIO_RESULT_FIELDS; diff --git a/client/components/common/fragments/Test.js b/client/components/common/fragments/Test.js new file mode 100644 index 000000000..9eb1b5af6 --- /dev/null +++ b/client/components/common/fragments/Test.js @@ -0,0 +1,59 @@ +import { gql } from '@apollo/client'; + +/** + * @param {'simple'|'all'} type + * @returns {*} + */ +const TEST_FIELDS = (type = 'simple') => { + switch (type) { + case 'simple': + return gql` + fragment TestFieldsSimple on Test { + __typename + id + title + rowNumber + renderedUrl + testFormatVersion + } + `; + case 'all': + return gql` + fragment TestFieldsAll on Test { + __typename + id + title + rowNumber + renderedUrl + testFormatVersion + ats { + id + key + name + } + renderedUrl + scenarios { + id + at { + id + key + name + } + commands { + id + text + atOperatingMode + } + } + assertions { + id + text + phrase + priority + } + } + `; + } +}; + +export default TEST_FIELDS; diff --git a/client/components/common/fragments/TestPlan.js b/client/components/common/fragments/TestPlan.js new file mode 100644 index 000000000..41294ef77 --- /dev/null +++ b/client/components/common/fragments/TestPlan.js @@ -0,0 +1,12 @@ +import { gql } from '@apollo/client'; + +const TEST_PLAN_FIELDS = gql` + fragment TestPlanFields on TestPlan { + __typename + id + title + directory + } +`; + +export default TEST_PLAN_FIELDS; diff --git a/client/components/common/fragments/TestPlanReport.js b/client/components/common/fragments/TestPlanReport.js new file mode 100644 index 000000000..21d3f92c7 --- /dev/null +++ b/client/components/common/fragments/TestPlanReport.js @@ -0,0 +1,16 @@ +import { gql } from '@apollo/client'; + +const TEST_PLAN_REPORT_FIELDS = gql` + fragment TestPlanReportFields on TestPlanReport { + __typename + id + metrics + isFinal + createdAt + markedFinalAt + conflictsLength + runnableTestsLength + } +`; + +export default TEST_PLAN_REPORT_FIELDS; diff --git a/client/components/common/fragments/TestPlanReportConflict.js b/client/components/common/fragments/TestPlanReportConflict.js new file mode 100644 index 000000000..bc546f245 --- /dev/null +++ b/client/components/common/fragments/TestPlanReportConflict.js @@ -0,0 +1,50 @@ +import { gql } from '@apollo/client'; + +const TEST_PLAN_REPORT_CONFLICT_FIELDS = gql` + fragment TestPlanReportConflictFields on TestPlanReportConflict { + __typename + source { + test { + id + title + rowNumber + } + scenario { + id + commands { + id + text + atOperatingMode + } + } + assertion { + id + text + phrase + priority + } + } + conflictingResults { + testPlanRun { + id + tester { + username + } + } + scenarioResult { + output + unexpectedBehaviors { + id + text + impact + details + } + } + assertionResult { + passed + } + } + } +`; + +export default TEST_PLAN_REPORT_CONFLICT_FIELDS; diff --git a/client/components/common/fragments/TestPlanReportStatus.js b/client/components/common/fragments/TestPlanReportStatus.js new file mode 100644 index 000000000..f5693d08c --- /dev/null +++ b/client/components/common/fragments/TestPlanReportStatus.js @@ -0,0 +1,90 @@ +import { gql } from '@apollo/client'; + +const TEST_PLAN_REPORT_STATUS_FIELDS = (type = 'simple') => { + switch (type) { + case 'simple': + return gql` + fragment TestPlanReportStatusFieldsSimple on TestPlanReportStatus { + __typename + testPlanReport { + metrics + draftTestPlanRuns { + testResults { + completedAt + } + } + } + } + `; + case 'all': + return gql` + fragment TestPlanReportStatusFieldsAll on TestPlanReportStatus { + __typename + isRequired + at { + id + key + name + atVersions { + id + name + releasedAt + supportedByAutomation + } + } + browser { + id + key + name + } + minimumAtVersion { + id + name + releasedAt + supportedByAutomation + } + exactAtVersion { + id + name + releasedAt + supportedByAutomation + } + testPlanReport { + id + metrics + isFinal + markedFinalAt + issues { + link + isOpen + feedbackType + } + draftTestPlanRuns { + tester { + username + } + testPlanReport { + id + } + testResults { + test { + id + } + atVersion { + id + name + } + browserVersion { + id + name + } + completedAt + } + } + } + } + `; + } +}; + +export default TEST_PLAN_REPORT_STATUS_FIELDS; diff --git a/client/components/common/fragments/TestPlanRun.js b/client/components/common/fragments/TestPlanRun.js new file mode 100644 index 000000000..aab8185b3 --- /dev/null +++ b/client/components/common/fragments/TestPlanRun.js @@ -0,0 +1,16 @@ +import { gql } from '@apollo/client'; + +const TEST_PLAN_RUN_FIELDS = gql` + fragment TestPlanRunFields on TestPlanRun { + __typename + id + initiatedByAutomation + tester { + id + username + isBot + } + } +`; + +export default TEST_PLAN_RUN_FIELDS; diff --git a/client/components/common/fragments/TestPlanVersion.js b/client/components/common/fragments/TestPlanVersion.js new file mode 100644 index 000000000..2f4c47677 --- /dev/null +++ b/client/components/common/fragments/TestPlanVersion.js @@ -0,0 +1,26 @@ +import { gql } from '@apollo/client'; + +const TEST_PLAN_VERSION_FIELDS = gql` + fragment TestPlanVersionFields on TestPlanVersion { + __typename + id + title + phase + gitSha + gitMessage + versionString + updatedAt + draftPhaseReachedAt + candidatePhaseReachedAt + recommendedPhaseReachedAt + recommendedPhaseTargetDate + deprecatedAt + testPageUrl + metadata + testPlan { + directory + } + } +`; + +export default TEST_PLAN_VERSION_FIELDS; diff --git a/client/components/common/fragments/TestResult.js b/client/components/common/fragments/TestResult.js new file mode 100644 index 000000000..6d001875f --- /dev/null +++ b/client/components/common/fragments/TestResult.js @@ -0,0 +1,12 @@ +import { gql } from '@apollo/client'; + +const TEST_RESULT_FIELDS = gql` + fragment TestResultFields on TestResult { + __typename + id + startedAt + completedAt + } +`; + +export default TEST_RESULT_FIELDS; diff --git a/client/components/common/fragments/User.js b/client/components/common/fragments/User.js new file mode 100644 index 000000000..2b1a30910 --- /dev/null +++ b/client/components/common/fragments/User.js @@ -0,0 +1,12 @@ +import { gql } from '@apollo/client'; + +const USER_FIELDS = gql` + fragment UserFields on User { + __typename + id + username + isBot + } +`; + +export default USER_FIELDS; diff --git a/client/components/common/fragments/index.js b/client/components/common/fragments/index.js new file mode 100644 index 000000000..99da71214 --- /dev/null +++ b/client/components/common/fragments/index.js @@ -0,0 +1,39 @@ +import AT_FIELDS from './At'; +import AT_VERSION_FIELDS from './AtVersion'; +import ASSERTION_RESULT_FIELDS from './AssertionResult'; +import BROWSER_FIELDS from './Browser'; +import BROWSER_VERSION_FIELDS from './BrowserVersion'; +import COLLECTION_JOB_FIELDS from './CollectionJob'; +import ISSUE_FIELDS from './Issue'; +import ME_FIELDS from './Me'; +import SCENARIO_RESULT_FIELDS from './ScenarioResult'; +import TEST_FIELDS from './Test'; +import TEST_PLAN_FIELDS from './TestPlan'; +import TEST_PLAN_REPORT_FIELDS from './TestPlanReport'; +import TEST_PLAN_REPORT_CONFLICT_FIELDS from './TestPlanReportConflict'; +import TEST_PLAN_REPORT_STATUS_FIELDS from './TestPlanReportStatus'; +import TEST_PLAN_RUN_FIELDS from './TestPlanRun'; +import TEST_PLAN_VERSION_FIELDS from './TestPlanVersion'; +import TEST_RESULT_FIELDS from './TestResult'; +import USER_FIELDS from './User'; + +export { + AT_FIELDS, + AT_VERSION_FIELDS, + ASSERTION_RESULT_FIELDS, + BROWSER_FIELDS, + BROWSER_VERSION_FIELDS, + COLLECTION_JOB_FIELDS, + ISSUE_FIELDS, + ME_FIELDS, + SCENARIO_RESULT_FIELDS, + TEST_FIELDS, + TEST_PLAN_FIELDS, + TEST_PLAN_REPORT_FIELDS, + TEST_PLAN_REPORT_CONFLICT_FIELDS, + TEST_PLAN_REPORT_STATUS_FIELDS, + TEST_PLAN_RUN_FIELDS, + TEST_PLAN_VERSION_FIELDS, + TEST_RESULT_FIELDS, + USER_FIELDS +}; diff --git a/client/components/common/proptypes/index.js b/client/components/common/proptypes/index.js new file mode 100644 index 000000000..7d98d1d78 --- /dev/null +++ b/client/components/common/proptypes/index.js @@ -0,0 +1,322 @@ +import PropTypes from 'prop-types'; + +export const AtPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + key: PropTypes.string.isRequired, + name: PropTypes.string.isRequired +}); + +export const AtVersionPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + releasedAt: PropTypes.string, + supportedByAutomation: PropTypes.bool +}); + +export const AssertionResultPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + passed: PropTypes.bool.isRequired, + assertion: PropTypes.shape({ + id: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + phrase: PropTypes.string, + priority: PropTypes.string + }).isRequired +}); + +export const BrowserPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + key: PropTypes.string.isRequired, + name: PropTypes.string.isRequired +}); + +export const BrowserVersionPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired +}); + +export const CollectionJobPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + status: PropTypes.oneOf([ + 'QUEUED', + 'RUNNING', + 'CANCELLED', + 'COMPLETED', + 'ERROR' + ]), + externalLogsUrl: PropTypes.string, + testStatus: PropTypes.arrayOf( + PropTypes.shape({ + test: PropTypes.shape({ + id: PropTypes.string.isRequired + }).isRequired, + status: PropTypes.string.isRequired + }) + ) +}); + +export const IssuePropType = PropTypes.shape({ + __typename: PropTypes.string, + link: PropTypes.string.isRequired, + isOpen: PropTypes.bool.isRequired, + feedbackType: PropTypes.string, + isCandidateReview: PropTypes.bool, + title: PropTypes.string, + author: PropTypes.string, + testNumberFilteredByAt: PropTypes.number, + createdAt: PropTypes.string, + closedAt: PropTypes.string +}); + +export const MePropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + username: PropTypes.string.isRequired, + roles: PropTypes.arrayOf(PropTypes.string) +}); + +export const ScenarioResultPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + output: PropTypes.string, + scenario: PropTypes.shape({ + commands: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + atOperatingMode: PropTypes.string + }) + ).isRequired + }).isRequired, + assertionResults: PropTypes.arrayOf(AssertionResultPropType), + mustAssertionResults: PropTypes.arrayOf(AssertionResultPropType), + shouldAssertionResults: PropTypes.arrayOf(AssertionResultPropType), + mayAssertionResults: PropTypes.arrayOf(AssertionResultPropType), + unexpectedBehaviors: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + impact: PropTypes.string, + details: PropTypes.string + }) + ) +}); + +export const TestPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + rowNumber: PropTypes.number, + renderedUrl: PropTypes.string, + testFormatVersion: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + ats: PropTypes.arrayOf(AtPropType), + scenarios: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + at: AtPropType, + commands: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + atOperatingMode: PropTypes.string + }) + ) + }) + ), + assertions: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + phrase: PropTypes.string, + priority: PropTypes.string + }) + ) +}); + +export const TestPlanPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + directory: PropTypes.string +}); + +export const TestPlanReportPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + metrics: PropTypes.object, + isFinal: PropTypes.bool, + createdAt: PropTypes.string, + markedFinalAt: PropTypes.string, + conflictsLength: PropTypes.number, + runnableTestsLength: PropTypes.number +}); + +export const TestPlanReportConflictPropType = PropTypes.shape({ + __typename: PropTypes.string, + source: PropTypes.shape({ + test: PropTypes.shape({ + id: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + rowNumber: PropTypes.number + }).isRequired, + scenario: PropTypes.shape({ + id: PropTypes.string.isRequired, + commands: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + atOperatingMode: PropTypes.string + }) + ) + }).isRequired, + assertion: PropTypes.shape({ + id: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + phrase: PropTypes.string, + priority: PropTypes.string + }).isRequired + }).isRequired, + conflictingResults: PropTypes.arrayOf( + PropTypes.shape({ + testPlanRun: PropTypes.shape({ + id: PropTypes.string.isRequired, + tester: PropTypes.shape({ + username: PropTypes.string.isRequired + }).isRequired + }).isRequired, + scenarioResult: PropTypes.shape({ + output: PropTypes.string, + unexpectedBehaviors: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + impact: PropTypes.string, + details: PropTypes.string + }) + ) + }), + assertionResult: PropTypes.shape({ + passed: PropTypes.bool.isRequired + }).isRequired + }) + ).isRequired +}); + +export const TestPlanReportStatusPropType = PropTypes.shape({ + __typename: PropTypes.string, + isRequired: PropTypes.bool, + at: AtPropType, + browser: BrowserPropType, + minimumAtVersion: AtVersionPropType, + exactAtVersion: AtVersionPropType, + testPlanReport: PropTypes.shape({ + id: PropTypes.string.isRequired, + metrics: PropTypes.object, + isFinal: PropTypes.bool, + markedFinalAt: PropTypes.string, + issues: PropTypes.arrayOf(IssuePropType), + draftTestPlanRuns: PropTypes.arrayOf( + PropTypes.shape({ + tester: PropTypes.shape({ + username: PropTypes.string.isRequired + }).isRequired, + testPlanReport: PropTypes.shape({ + id: PropTypes.string.isRequired + }).isRequired, + testResults: PropTypes.arrayOf( + PropTypes.shape({ + test: PropTypes.shape({ + id: PropTypes.string.isRequired + }).isRequired, + atVersion: AtVersionPropType, + browserVersion: BrowserVersionPropType, + completedAt: PropTypes.string + }) + ) + }) + ) + }).isRequired +}); + +export const TestPlanRunPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string, + initiatedByAutomation: PropTypes.bool, + tester: PropTypes.shape({ + id: PropTypes.string, + username: PropTypes.string.isRequired, + isBot: PropTypes.bool + }).isRequired +}); + +export const TestPlanVersionPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + phase: PropTypes.string, + gitSha: PropTypes.string, + gitMessage: PropTypes.string, + versionString: PropTypes.string, + updatedAt: PropTypes.string, + draftPhaseReachedAt: PropTypes.string, + candidatePhaseReachedAt: PropTypes.string, + recommendedPhaseReachedAt: PropTypes.string, + recommendedPhaseTargetDate: PropTypes.string, + deprecatedAt: PropTypes.string, + testPageUrl: PropTypes.string, + metadata: PropTypes.object, + testPlan: PropTypes.shape({ + directory: PropTypes.string + }).isRequired +}); + +export const TestResultPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string, + startedAt: PropTypes.string, + completedAt: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]) +}); + +export const UserPropType = PropTypes.shape({ + __typename: PropTypes.string, + id: PropTypes.string.isRequired, + username: PropTypes.string.isRequired, + isBot: PropTypes.bool +}); + +export const ModalActionPropType = PropTypes.shape({ + label: PropTypes.string, + onClick: PropTypes.func, + variant: PropTypes.string, + className: PropTypes.string, + testId: PropTypes.string, + component: PropTypes.elementType, + props: PropTypes.object +}); + +export const ActionButtonPropType = PropTypes.shape({ + label: PropTypes.string, + action: PropTypes.func +}); + +export const AtOutputPropType = PropTypes.shape({ + description: PropTypes.arrayOf( + PropTypes.oneOfType([ + PropTypes.string, + PropTypes.shape({ + required: PropTypes.bool.isRequired, + highlightRequired: PropTypes.bool.isRequired, + description: PropTypes.string.isRequired + }) + ]) + ).isRequired, + value: PropTypes.string.isRequired, + change: PropTypes.func.isRequired, + focus: PropTypes.bool.isRequired +}); diff --git a/client/hooks/useUrlTestIndex.js b/client/hooks/useUrlTestIndex.js new file mode 100644 index 000000000..68802665e --- /dev/null +++ b/client/hooks/useUrlTestIndex.js @@ -0,0 +1,33 @@ +import { useLocation, useNavigate } from 'react-router-dom'; +import { useEffect, useState } from 'react'; + +export const useUrlTestIndex = maxTestIndex => { + const location = useLocation(); + const navigate = useNavigate(); + const [currentTestIndex, setCurrentTestIndex] = useState(0); + + const getTestIndex = () => { + // Remove the '#' character + const fragment = parseInt(location.hash.slice(1), 10) || 1; + + if (!maxTestIndex || maxTestIndex < 1) { + // If the max test index is less than 1, return 0 + return 0; + } + // Subtract 1 to make it 0-indexed + // and clamp to the max test index + return Math.max(0, Math.min(fragment - 1, maxTestIndex - 1)); + }; + + useEffect(() => { + setCurrentTestIndex(getTestIndex()); + }, [location.hash, maxTestIndex]); + + const updateTestIndex = index => { + // Add 1 to make it 1-indexed + const newIndex = index + 1; + navigate(`${location.pathname}#${newIndex}`, { replace: true }); + }; + + return [currentTestIndex, updateTestIndex]; +}; diff --git a/client/package.json b/client/package.json index 1e167c527..9b9eebaf7 100644 --- a/client/package.json +++ b/client/package.json @@ -11,7 +11,8 @@ "lint": "eslint --ext js,jsx .", "storybook": "start-storybook -p 6006", "build-storybook": "build-storybook", - "lighthouse": "lhci autorun" + "lighthouse": "lhci autorun", + "update-snapshots": "DOTENV_CONFIG_PATH=../config/test.env node -r dotenv/config tests/e2e/snapshots/takeSnapshots.js" }, "repository": { "type": "git", @@ -72,8 +73,6 @@ "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.11.0", "dotenv-webpack": "^8.1.0", - "enzyme": "^3.11.0", - "enzyme-adapter-react-16": "^1.15.8", "eslint": "^8.57.0", "eslint-config-prettier": "^8.10.0", "eslint-plugin-jest": "^27.9.0", @@ -83,9 +82,8 @@ "file-loader": "^6.0.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "jest-enzyme": "^7.1.2", "prettier": "^2.8.8", - "puppeteer": "^21.11.0", + "puppeteer": "^23.0.2", "storybook-addon-apollo-client": "^4.1.4", "storybook-react-router": "^1.0.8", "style-loader": "^3.3.4", diff --git a/client/static/index.html b/client/static/index.html index 057213870..5db6d0959 100644 --- a/client/static/index.html +++ b/client/static/index.html @@ -5,6 +5,7 @@ + ARIA-AT App diff --git a/client/tests/App.test.jsx b/client/tests/App.test.jsx deleted file mode 100644 index 8d8400f69..000000000 --- a/client/tests/App.test.jsx +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @jest-environment jsdom - */ - -import React from 'react'; -import Enzyme, { shallow } from 'enzyme'; -import EnzymeAdapter from 'enzyme-adapter-react-16'; -import App from '../components/App'; -import GraphQLProvider from '../components/GraphQLProvider'; - -Enzyme.configure({ adapter: new EnzymeAdapter() }); - -const setup = () => { - const wrapper = shallow( - - - - ).dive(); - return wrapper; -}; - -test('renders without crashing', () => { - const wrapper = setup(); - expect(wrapper).toBeTruthy(); -}); diff --git a/client/tests/AssignTesterDropdown.test.jsx b/client/tests/AssignTesterDropdown.test.jsx index 4fffe9257..d9ec3d2e4 100644 --- a/client/tests/AssignTesterDropdown.test.jsx +++ b/client/tests/AssignTesterDropdown.test.jsx @@ -75,16 +75,19 @@ useMutation.mockImplementation(mutation => { const getMocks = (atKey, browserKey) => { const at = { nvda: { + __typename: 'At', id: '2', name: 'NVDA', key: 'nvda' }, jaws: { + __typename: 'At', id: '1', name: 'JAWS', key: 'jaws' }, voiceover_macos: { + __typename: 'At', id: '3', name: 'VoiceOver for MacOS', key: 'voiceover_macos' @@ -93,16 +96,19 @@ const getMocks = (atKey, browserKey) => { const browser = { chrome: { + __typename: 'Browser', id: '2', name: 'Chrome', key: 'chrome' }, safari_macos: { + __typename: 'Browser', id: '3', name: 'Safari for MacOS', key: 'safari_macos' }, voiceover_macos: { + __typename: 'Browser', id: '3', name: 'VoiceOver for MacOS', key: 'voiceover_macos' diff --git a/client/tests/DataManagement.test.jsx b/client/tests/DataManagement.test.jsx index c379eea11..e36c91d31 100644 --- a/client/tests/DataManagement.test.jsx +++ b/client/tests/DataManagement.test.jsx @@ -2,16 +2,10 @@ * @jest-environment jsdom */ -import React, { act } from 'react'; -import { render, renderHook, waitFor } from '@testing-library/react'; -import { InMemoryCache } from '@apollo/client'; -import { MockedProvider } from '@apollo/client/testing'; -import { BrowserRouter } from 'react-router-dom'; +import { act } from 'react'; +import { renderHook } from '@testing-library/react'; import '@testing-library/jest-dom'; -import DataManagement from '../components/DataManagement'; -// eslint-disable-next-line jest/no-mocks-import -import { DATA_MANAGEMENT_PAGE_POPULATED_MOCK_DATA } from './__mocks__/GraphQLMocks'; import { useDataManagementTableFiltering, useDataManagementTableSorting, @@ -24,62 +18,6 @@ import { DATA_MANAGEMENT_TABLE_SORT_OPTIONS } from '../components/DataManagement/utils'; import { TABLE_SORT_ORDERS } from '../components/common/SortableTableHeader'; -import { AriaLiveRegionProvider } from '../components/providers/AriaLiveRegionProvider'; - -const setup = (mocks = []) => { - return render( - - - - - - - - ); -}; - -describe('Data Management page', () => { - let wrapper; - - beforeEach(() => { - wrapper = setup(DATA_MANAGEMENT_PAGE_POPULATED_MOCK_DATA); - }); - - it('renders loading state on initialization', async () => { - const { getByTestId } = wrapper; - const element = getByTestId('page-status'); - - expect(element).toBeTruthy(); - expect(element).toHaveTextContent('Loading'); - }); - - it('renders Status Summary component', async () => { - // allow page time to load - await waitFor(() => new Promise(res => setTimeout(res, 0))); - - const { queryAllByText } = wrapper; - const statusSummaryElement = queryAllByText(/Test Plans Status Summary/i); - const testPlanElement = queryAllByText(/Test Plan/i); - const coveredAtElement = queryAllByText(/Covered AT/i); - const overallStatusElement = queryAllByText(/Overall Status/i); - const rdElement = queryAllByText(/R&D Version/i); - const draftElement = queryAllByText(/Draft Review/i); - const candidateElement = queryAllByText(/Candidate Review/i); - const recommendedElement = queryAllByText(/Recommended Version/i); - - expect(statusSummaryElement.length).toBeGreaterThanOrEqual(1); - expect(testPlanElement.length).toBeGreaterThanOrEqual(1); - expect(coveredAtElement.length).toBeGreaterThanOrEqual(1); - expect(overallStatusElement.length).toBeGreaterThanOrEqual(1); - expect(rdElement.length).toBeGreaterThanOrEqual(1); - expect(draftElement.length).toBeGreaterThanOrEqual(1); - expect(candidateElement.length).toBeGreaterThanOrEqual(1); - expect(recommendedElement.length).toBeGreaterThanOrEqual(1); - }); -}); const testPlans = [ { title: 'Test A', directory: 'dirA', id: '1' }, diff --git a/client/tests/TestRun.test.jsx b/client/tests/TestRun.test.jsx deleted file mode 100644 index d74b000d5..000000000 --- a/client/tests/TestRun.test.jsx +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @jest-environment jsdom - */ - -import React from 'react'; -import Enzyme, { shallow } from 'enzyme'; -import EnzymeAdapter from 'enzyme-adapter-react-16'; -Enzyme.configure({ adapter: new EnzymeAdapter() }); -import { findByTestAttr } from './util'; -import TestRun from '../components/TestRun'; - -const setup = () => { - // Step into the higher order connected component and step into the contents of the UserSettings component - const wrapper = shallow( - - ) - .dive() - .dive(); - return wrapper; -}; - -describe.skip('render', () => { - describe('loading when there are no tests', () => { - let wrapper; - beforeEach(() => { - wrapper = setup(); - }); - test('renders not logged in text', () => { - const component = findByTestAttr(wrapper, 'test-run-page-status'); - expect(component.text()).toContain('Loading'); - }); - }); - describe('tests are loaded', () => { - let wrapper; - beforeEach(() => { - wrapper = setup(); - wrapper.setState({ currentTestIndex: 1 }); - }); - test('renders testing headings', () => { - let component = findByTestAttr(wrapper, 'apg-example-name'); - expect(component.length).toBe(1); - expect(component.text()).toContain('Test Plan'); - - component = findByTestAttr(wrapper, 'at-browser'); - expect(component.length).toBe(1); - expect(component.text()).toContain('with'); - }); - }); -}); diff --git a/client/tests/UserSettings.test.jsx b/client/tests/UserSettings.test.jsx deleted file mode 100644 index 6eed0a264..000000000 --- a/client/tests/UserSettings.test.jsx +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react'; -import Enzyme, { shallow } from 'enzyme'; -import EnzymeAdapter from 'enzyme-adapter-react-16'; -Enzyme.configure({ adapter: new EnzymeAdapter() }); -import { findByTestAttr } from './util'; -import UserSettings from '../components/UserSettings'; - -const setup = () => { - // Step into the higher order connected component and step into the contents of the UserSettings component - const wrapper = shallow() - .dive() - .dive(); - return wrapper; -}; - -describe.skip('render', () => { - describe('user is not signed in', () => { - let wrapper; - beforeEach(() => { - wrapper = setup(); - }); - test('renders component without error', () => { - const component = findByTestAttr(wrapper, 'user-settings-contents'); - expect(component.length).toBe(1); - }); - test('renders not signed in text', () => { - const component = findByTestAttr(wrapper, 'user-settings-unauthorized'); - expect(component.length).toBe(1); - }); - }); - describe('user is signed in', () => { - let wrapper; - beforeEach(() => { - wrapper = setup(); - }); - test('renders component without error', () => { - const component = findByTestAttr(wrapper, 'user-settings-contents'); - expect(component.length).toBe(1); - }); - test('renders username', () => { - const component = findByTestAttr(wrapper, 'user-settings-authorized'); - expect(component.length).toBe(1); - expect(component.text()).toContain('User Details'); - expect(component.find('a').at(0).props().href).toContain( - 'https://github.com' - ); - }); - }); -}); diff --git a/client/tests/__mocks__/GraphQLMocks/DataManagementPagePopulatedMock.js b/client/tests/__mocks__/GraphQLMocks/DataManagementPagePopulatedMock.js deleted file mode 100644 index 7053cf593..000000000 --- a/client/tests/__mocks__/GraphQLMocks/DataManagementPagePopulatedMock.js +++ /dev/null @@ -1,7417 +0,0 @@ -export default ( - meQuery, - dataManagementPageQuery, - testPlanReportStatusDialogQuery -) => [ - { - request: { - query: meQuery - }, - result: { - data: { - me: { - id: '1', - username: 'foo-bar', - roles: ['ADMIN', 'TESTER'] - } - } - } - }, - { - request: { - query: dataManagementPageQuery - }, - result: { - data: { - me: { - id: '1', - username: 'foo-bar', - roles: ['ADMIN', 'TESTER'] - }, - ats: [ - { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - releasedAt: '2021-11-01T04:00:00.000Z', - supportedByAutomation: false - } - ], - browsers: [ - { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - { - id: '1', - key: 'firefox', - name: 'Firefox' - } - ], - candidateBrowsers: [{ id: '2' }], - recommendedBrowsers: [{ id: '1' }, { id: '2' }] - }, - { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - releasedAt: '2021-02-19T05:00:00.000Z', - supportedByAutomation: false - } - ], - browsers: [ - { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - { - id: '1', - key: 'firefox', - name: 'Firefox' - } - ], - candidateBrowsers: [{ id: '2' }], - recommendedBrowsers: [{ id: '1' }, { id: '2' }] - }, - { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - releasedAt: '2019-09-01T04:00:00.000Z', - supportedByAutomation: false - } - ], - browsers: [ - { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - { - id: '3', - key: 'safari_macos', - name: 'Safari' - } - ], - candidateBrowsers: [{ id: '3' }], - recommendedBrowsers: [{ id: '2' }, { id: '3' }] - } - ], - testPlans: [ - { - id: '27', - directory: 'radiogroup-aria-activedescendant', - title: 'Radio Group Example Using aria-activedescendant' - }, - { - id: '28', - directory: 'radiogroup-roving-tabindex', - title: 'Radio Group Example Using Roving tabindex' - }, - { - id: '31', - directory: 'slider-multithumb', - title: 'Horizontal Multi-Thumb Slider' - }, - { - id: '16', - directory: 'link-css', - title: - 'Link Example 3 (CSS :before content property on a span element)' - }, - { - id: '17', - directory: 'link-img-alt', - title: 'Link Example 2 (img element with alt attribute)' - }, - { - id: '1', - directory: 'alert', - title: 'Alert Example' - }, - { - id: '13', - directory: 'disclosure-navigation', - title: 'Disclosure Navigation Menu Example' - }, - { - id: '5', - directory: 'checkbox-tri-state', - title: 'Checkbox Example (Mixed-State)' - }, - { - id: '3', - directory: 'breadcrumb', - title: 'Breadcrumb Example' - }, - { - id: '19', - directory: 'main', - title: 'Main Landmark' - }, - { - id: '24', - directory: 'meter', - title: 'Meter' - }, - { - id: '32', - directory: 'switch', - title: 'Switch Example' - }, - { - id: '26', - directory: 'modal-dialog', - title: 'Modal Dialog Example' - }, - { - id: '22', - directory: 'menu-button-navigation', - title: 'Navigation Menu Button' - }, - { - id: '34', - directory: 'toggle-button', - title: 'Toggle Button' - }, - { - id: '18', - directory: 'link-span-text', - title: 'Link Example 1 (span element with text content)' - }, - { - id: '8', - directory: 'command-button', - title: 'Command Button Example' - }, - { - id: '15', - directory: 'horizontal-slider', - title: 'Color Viewer Slider' - }, - { - id: '6', - directory: 'combobox-autocomplete-both-updated', - title: 'Combobox with Both List and Inline Autocomplete Example' - }, - { - id: '7', - directory: 'combobox-select-only', - title: 'Select Only Combobox Example' - }, - { - id: '4', - directory: 'checkbox', - title: 'Checkbox Example (Two State)' - }, - { - id: '9', - directory: 'complementary', - title: 'Complementary Landmark' - }, - { - id: '10', - directory: 'contentinfo', - title: 'Contentinfo Landmark' - }, - { - id: '11', - directory: 'datepicker-spin-button', - title: 'Date Picker Spin Button Example' - }, - { - id: '12', - directory: 'disclosure-faq', - title: 'Disclosure of Answers to Frequently Asked Questions Example' - }, - { - id: '14', - directory: 'form', - title: 'Form Landmark' - }, - { - id: '20', - directory: 'menu-button-actions', - title: 'Action Menu Button Example Using element.focus()' - }, - { - id: '21', - directory: 'menu-button-actions-active-descendant', - title: 'Action Menu Button Example Using aria-activedescendant' - }, - { - id: '23', - directory: 'menubar-editor', - title: 'Editor Menubar Example' - }, - { - id: '25', - directory: 'minimal-data-grid', - title: 'Data Grid Example 1: Minimal Data Grid' - }, - { - id: '29', - directory: 'rating-slider', - title: 'Rating Slider' - }, - { - id: '30', - directory: 'seek-slider', - title: 'Media Seek Slider' - }, - { - id: '33', - directory: 'tabs-manual-activation', - title: 'Tabs with Manual Activation' - }, - { - id: '35', - directory: 'vertical-temperature-slider', - title: 'Vertical Temperature Slider' - }, - { - id: '2', - directory: 'banner', - title: 'Banner Landmark' - } - ], - deprecatedTestPlanVersions: [], - testPlanVersions: [ - { - id: '28', - title: 'Radio Group Example Using Roving tabindex', - phase: 'RD', - gitSha: '1768070bd68beefef29284b568d2da910b449c14', - gitMessage: - 'Remove Tab and Shift+Tab from radiogroup tests when navigating out of the start and end of a radio group (reading mode and VoiceOver only) (#928)', - updatedAt: '2023-04-10T18:22:22.000Z', - versionString: 'V23.04.10', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'radiogroup-roving-tabindex' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '27', - title: 'Radio Group Example Using aria-activedescendant', - phase: 'RD', - gitSha: '1768070bd68beefef29284b568d2da910b449c14', - gitMessage: - 'Remove Tab and Shift+Tab from radiogroup tests when navigating out of the start and end of a radio group (reading mode and VoiceOver only) (#928)', - updatedAt: '2023-04-10T18:22:22.000Z', - versionString: 'V23.04.10', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'radiogroup-aria-activedescendant' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '31', - title: 'Horizontal Multi-Thumb Slider', - phase: 'RD', - gitSha: 'b5fe3efd569518e449ef9a0978b0dec1f2a08bd6', - gitMessage: - 'Create tests for APG design pattern example: Horizontal Multi-Thumb Slider (#511)', - updatedAt: '2023-03-20T21:24:41.000Z', - versionString: 'V23.03.20', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'slider-multithumb' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '16', - title: - 'Link Example 3 (CSS :before content property on a span element)', - phase: 'RD', - gitSha: '7a8454bca6de980199868101431817cea03cce35', - gitMessage: - 'Create tests for APG design pattern example: Link Example 3 (CSS :before content property on a span element) (#518)', - updatedAt: '2023-03-13T22:10:13.000Z', - versionString: 'V23.03.13', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'link-css' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '17', - title: 'Link Example 2 (img element with alt attribute)', - phase: 'RD', - gitSha: 'dc637636cff74b51f5c468ff3b81bd1f38aefbb2', - gitMessage: - 'Create tests for APG design pattern example: Link Example 2 (img element with alt attribute) (#516)', - updatedAt: '2023-03-13T19:51:48.000Z', - versionString: 'V23.03.13', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'link-img-alt' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '1', - title: 'Alert Example', - phase: 'DRAFT', - gitSha: '0928bcf530efcf4faa677285439701537674e014', - gitMessage: 'Alert and Radiogroup/activedescendent updates (#865)', - updatedAt: '2022-12-08T21:47:42.000Z', - versionString: 'V22.12.08', - draftPhaseReachedAt: '2022-07-06T00:00:00.000Z', - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'alert' - }, - testPlanReports: [ - { - id: '7', - metrics: {}, - markedFinalAt: null, - isFinal: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - issues: [], - draftTestPlanRuns: [] - } - ], - metadata: {} - }, - { - id: '13', - title: 'Disclosure Navigation Menu Example', - phase: 'RD', - gitSha: '179ba0f438aaa5781b3ec8a4033d6bf9f757360b', - gitMessage: - 'Delete up arrow command for VoiceOver when navigating backwards to a disclosure button (#845)', - updatedAt: '2022-10-31T19:29:17.000Z', - versionString: 'V22.10.31', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'disclosure-navigation' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '3', - title: 'Breadcrumb Example', - phase: 'RD', - gitSha: '1aa3b74d24d340362e9f511eae33788d55487d12', - gitMessage: - 'Add down arrow command to the Navigate forwards out of the Breadcrumb navigation landmark task for JAWS (#803)', - updatedAt: '2022-08-10T18:44:16.000Z', - versionString: 'V22.08.10', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'breadcrumb' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '19', - title: 'Main Landmark', - phase: 'RD', - gitSha: 'c87a66ea13a2b6fac6d79fe1fb0b7a2f721dcd22', - gitMessage: - 'Create updated tests for APG design pattern example: Main landmark (#707)', - updatedAt: '2022-08-05T17:46:37.000Z', - versionString: 'V22.08.05', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'main' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '24', - title: 'Meter', - phase: 'RD', - gitSha: '32d2d9db48becfc008fc566b569ac1563576ceb9', - gitMessage: - 'Create updated tests for APG design pattern example: Meter (#692)', - updatedAt: '2022-08-05T17:02:59.000Z', - versionString: 'V22.08.05', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'meter' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '32', - title: 'Switch Example', - phase: 'RD', - gitSha: '9d0e4e3d1040d64d9db69647e615c4ec0be723c2', - gitMessage: - 'Create updated tests for APG design pattern example: Switch (#691)', - updatedAt: '2022-08-05T16:13:44.000Z', - versionString: 'V22.08.05', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'switch' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '22', - title: 'Navigation Menu Button', - phase: 'RD', - gitSha: 'ecf05f484292189789f4db8b1ec41b19db38e567', - gitMessage: - 'Tasks 4, 5 and 6: corrected link name "Navigate backwards from here" (#734)', - updatedAt: '2022-05-26T16:14:17.000Z', - versionString: 'V22.05.26', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'menu-button-navigation' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '34', - title: 'Toggle Button', - phase: 'DRAFT', - gitSha: '022340081280b8cafb8ae0716a5b67e9ab942ef4', - gitMessage: - 'Delete duplicated assertion for operating a not pressed togle button (VoiceOver) (#716)', - updatedAt: '2022-05-18T20:51:40.000Z', - versionString: 'V22.05.18', - draftPhaseReachedAt: '2022-07-06T00:00:00.000Z', - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'toggle-button' - }, - testPlanReports: [ - { - id: '1', - metrics: { - testsCount: 16, - supportLevel: 'FAILING', - conflictsCount: 0, - supportPercent: 93, - testsFailedCount: 14, - testsPassedCount: 2, - shouldFormatted: false, - mustFormatted: '28 of 30 passed', - shouldAssertionsCount: 0, - mustAssertionsCount: 30, - unexpectedBehaviorCount: 1, - unexpectedBehaviorsFormatted: '1 found', - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 0, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 28 - }, - markedFinalAt: null, - isFinal: false, - at: { - id: '1', - key: 'jaws', - name: 'JAWS' - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '1' - }, - testResults: [ - { - test: { - id: 'OWY5NeyIyIjoiMzQifQTRmOD' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:07.154Z' - }, - { - test: { - id: 'NGFjMeyIyIjoiMzQifQjQxY2' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: null - }, - { - test: { - id: 'NTAwOeyIyIjoiMzQifQWI5YT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: null - }, - { - test: { - id: 'YThjMeyIyIjoiMzQifQzIyYT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: null - }, - { - test: { - id: 'YTgxMeyIyIjoiMzQifQzExOW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:07.381Z' - }, - { - test: { - id: 'NGMwNeyIyIjoiMzQifQ2IwN2' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:07.464Z' - }, - { - test: { - id: 'YzQxNeyIyIjoiMzQifQjY5ND' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:07.537Z' - }, - { - test: { - id: 'MjgwNeyIyIjoiMzQifQzk3YT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:07.610Z' - } - ] - } - ] - } - ], - metadata: {} - }, - { - id: '8', - title: 'Command Button Example', - phase: 'RD', - gitSha: '0c466eec96c8cafc9961232c85e14758c4589525', - gitMessage: - 'Fix navigation link positions in three test plans: link, command button and toggle button (#709)', - updatedAt: '2022-05-04T21:33:31.000Z', - versionString: 'V22.05.04', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'command-button' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '18', - title: 'Link Example 1 (span element with text content)', - phase: 'RD', - gitSha: '0c466eec96c8cafc9961232c85e14758c4589525', - gitMessage: - 'Fix navigation link positions in three test plans: link, command button and toggle button (#709)', - updatedAt: '2022-05-04T21:33:31.000Z', - versionString: 'V22.05.04', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'link-span-text' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '15', - title: 'Color Viewer Slider', - phase: 'RD', - gitSha: '1c6ef2fbef5fc056c622c802bebedaa14f2c8d40', - gitMessage: - 'Create updated tests for APG design pattern example: Color Viewer Slider (#686)', - updatedAt: '2022-04-14T18:06:40.000Z', - versionString: 'V22.04.14', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'horizontal-slider' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '6', - title: 'Combobox with Both List and Inline Autocomplete Example', - phase: 'RD', - gitSha: '6b2cbcbdbd5f6867cd3c9e96362817c353335187', - gitMessage: "typo: double word 'the' (#595)", - updatedAt: '2022-03-29T16:02:56.000Z', - versionString: 'V22.03.29', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'combobox-autocomplete-both-updated' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '21', - title: 'Action Menu Button Example Using aria-activedescendant', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'menu-button-actions-active-descendant' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '20', - title: 'Action Menu Button Example Using element.focus()', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'menu-button-actions' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '2', - title: 'Banner Landmark', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'banner' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '4', - title: 'Checkbox Example (Two State)', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'checkbox' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '9', - title: 'Complementary Landmark', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'complementary' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '10', - title: 'Contentinfo Landmark', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'contentinfo' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '25', - title: 'Data Grid Example 1: Minimal Data Grid', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'minimal-data-grid' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '11', - title: 'Date Picker Spin Button Example', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'datepicker-spin-button' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '12', - title: - 'Disclosure of Answers to Frequently Asked Questions Example', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'disclosure-faq' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '23', - title: 'Editor Menubar Example', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'menubar-editor' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '14', - title: 'Form Landmark', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'form' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '30', - title: 'Media Seek Slider', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'seek-slider' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '29', - title: 'Rating Slider', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'rating-slider' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '7', - title: 'Select Only Combobox Example', - phase: 'DRAFT', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: '2022-07-06T00:00:00.000Z', - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'combobox-select-only' - }, - testPlanReports: [ - { - id: '2', - metrics: { - testsCount: 21, - supportLevel: 'FAILING', - conflictsCount: 5, - supportPercent: 96, - testsFailedCount: 16, - testsPassedCount: 5, - shouldFormatted: '3 of 3 passed', - mustFormatted: '48 of 50 passed', - shouldAssertionsCount: 3, - mustAssertionsCount: 50, - unexpectedBehaviorCount: 3, - unexpectedBehaviorsFormatted: '3 found', - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 3, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 48 - }, - markedFinalAt: null, - isFinal: false, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'tom-proudfeet' - }, - testPlanReport: { - id: '2' - }, - testResults: [ - { - test: { - id: 'Nzg5NeyIyIjoiNyJ9zNjZj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:08.240Z' - }, - { - test: { - id: 'MmY0YeyIyIjoiNyJ9jRkZD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:08.332Z' - }, - { - test: { - id: 'ZjUwNeyIyIjoiNyJ9mE2ZT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:08.412Z' - }, - { - test: { - id: 'MDNiMeyIyIjoiNyJ9Dk1MT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:08.501Z' - }, - { - test: { - id: 'MjRmNeyIyIjoiNyJ92MyMT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:08.593Z' - }, - { - test: { - id: 'ZmVlMeyIyIjoiNyJ9mUyYj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: null - }, - { - test: { - id: 'YWFiNeyIyIjoiNyJ9zE2Zj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:08.811Z' - }, - { - test: { - id: 'YjZkYeyIyIjoiNyJ9WIxZm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:08.902Z' - }, - { - test: { - id: 'ZmIzMeyIyIjoiNyJ9TQ1NW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:08.996Z' - } - ] - }, - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '2' - }, - testResults: [ - { - test: { - id: 'Nzg5NeyIyIjoiNyJ9zNjZj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:07.718Z' - }, - { - test: { - id: 'MmY0YeyIyIjoiNyJ9jRkZD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:07.813Z' - }, - { - test: { - id: 'ZjUwNeyIyIjoiNyJ9mE2ZT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:07.914Z' - }, - { - test: { - id: 'MDNiMeyIyIjoiNyJ9Dk1MT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:07.988Z' - }, - { - test: { - id: 'MjRmNeyIyIjoiNyJ92MyMT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:08.074Z' - }, - { - test: { - id: 'ZmVlMeyIyIjoiNyJ9mUyYj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: null - } - ] - } - ] - } - ], - metadata: {} - }, - { - id: '33', - title: 'Tabs with Manual Activation', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'tabs-manual-activation' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '35', - title: 'Vertical Temperature Slider', - phase: 'RD', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - versionString: 'V22.03.17', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'vertical-temperature-slider' - }, - testPlanReports: [], - metadata: {} - }, - { - id: '5', - title: 'Checkbox Example (Mixed-State)', - phase: 'RECOMMENDED', - gitSha: 'b3d0576a2901ea7f100f49a994b64edbecf81cff', - gitMessage: 'Modify VoiceOver commands for task 7 (#842)', - updatedAt: '2022-10-24T21:33:12.000Z', - versionString: 'V22.10.24', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: '2022-07-06T00:00:00.000Z', - recommendedPhaseTargetDate: '2023-01-02T00:00:00.000Z', - recommendedPhaseReachedAt: '2023-01-03T00:00:00.000Z', - testPlan: { - directory: 'checkbox-tri-state' - }, - testPlanReports: [ - { - id: '6', - metrics: { - testsCount: 7, - supportLevel: 'FAILING', - conflictsCount: 0, - supportPercent: 96, - testsFailedCount: 3, - testsPassedCount: 4, - shouldFormatted: '4 of 4 passed', - mustFormatted: '44 of 46 passed', - shouldAssertionsCount: 4, - mustAssertionsCount: 46, - unexpectedBehaviorCount: 0, - unexpectedBehaviorsFormatted: false, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 4, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 44 - }, - markedFinalAt: '2022-07-06T00:00:00.000Z', - isFinal: true, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS' - }, - browser: { - id: '3', - key: 'safari_macos', - name: 'Safari' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'tom-proudfeet' - }, - testPlanReport: { - id: '6' - }, - testResults: [ - { - test: { - id: 'YTE3NeyIyIjoiNSJ9WJlMj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.341Z' - }, - { - test: { - id: 'YWJiOeyIyIjoiNSJ9GQ5Zm' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.405Z' - }, - { - test: { - id: 'ZGFlYeyIyIjoiNSJ9TJlMW' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.474Z' - }, - { - test: { - id: 'YjI2MeyIyIjoiNSJ9WE1OT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.537Z' - }, - { - test: { - id: 'ZjAwZeyIyIjoiNSJ9TZmZj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.605Z' - }, - { - test: { - id: 'MGRjZeyIyIjoiNSJ9WNiZD' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.670Z' - }, - { - test: { - id: 'OTZmYeyIyIjoiNSJ9TU5Ym' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.739Z' - } - ] - } - ] - }, - { - id: '12', - metrics: { - testsCount: 14, - supportLevel: 'FULL', - conflictsCount: 0, - supportPercent: 100, - testsFailedCount: 12, - testsPassedCount: 2, - shouldFormatted: false, - mustFormatted: '25 of 25 passed', - shouldAssertionsCount: 0, - mustAssertionsCount: 25, - unexpectedBehaviorCount: 0, - unexpectedBehaviorsFormatted: false, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 25 - }, - markedFinalAt: null, - isFinal: false, - at: { - id: '1', - key: 'jaws', - name: 'JAWS' - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '12' - }, - testResults: [ - { - test: { - id: 'MTVlZeyIyIjoiNSJ9DUzMz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:11.764Z' - }, - { - test: { - id: 'OThhMeyIyIjoiNSJ9WMxM2' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:11.828Z' - }, - { - test: { - id: 'YWNhNeyIyIjoiNSJ9TliN2' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:11.892Z' - } - ] - } - ] - }, - { - id: '13', - metrics: { - testsCount: 14, - supportLevel: 'FULL', - conflictsCount: 0, - supportPercent: 100, - testsFailedCount: 12, - testsPassedCount: 2, - shouldFormatted: false, - mustFormatted: '25 of 25 passed', - shouldAssertionsCount: 0, - mustAssertionsCount: 25, - unexpectedBehaviorCount: 0, - unexpectedBehaviorsFormatted: false, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 25 - }, - markedFinalAt: null, - isFinal: false, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '13' - }, - testResults: [ - { - test: { - id: 'MTVlZeyIyIjoiNSJ9DUzMz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:11.955Z' - }, - { - test: { - id: 'OThhMeyIyIjoiNSJ9WMxM2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:12.017Z' - }, - { - test: { - id: 'YWNhNeyIyIjoiNSJ9TliN2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:12.083Z' - } - ] - } - ] - } - ], - metadata: {} - }, - { - id: '26', - title: 'Modal Dialog Example', - phase: 'CANDIDATE', - gitSha: 'd0e16b42179de6f6c070da2310e99de837c71215', - gitMessage: - 'Delete down arrow command for navigating to the beginning of a dialog with JAWS and add the ESC command to exit forms or focus mode (#759)', - updatedAt: '2022-06-22T17:56:16.000Z', - versionString: 'V22.06.22', - draftPhaseReachedAt: '2022-07-06T00:00:00.000Z', - candidatePhaseReachedAt: '2022-07-06T00:00:00.000Z', - recommendedPhaseTargetDate: '2023-01-02T00:00:00.000Z', - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'modal-dialog' - }, - testPlanReports: [ - { - id: '10', - metrics: { - testsCount: 11, - supportLevel: 'FULL', - conflictsCount: 0, - supportPercent: 100, - testsFailedCount: 9, - testsPassedCount: 2, - shouldFormatted: false, - mustFormatted: '14 of 14 passed', - shouldAssertionsCount: 0, - mustAssertionsCount: 14, - unexpectedBehaviorCount: 0, - unexpectedBehaviorsFormatted: false, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 14 - }, - markedFinalAt: null, - isFinal: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS' - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '10' - }, - testResults: [ - { - test: { - id: 'MzlmYeyIyIjoiMjYifQzIxY2' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:11.295Z' - }, - { - test: { - id: 'N2FkZeyIyIjoiMjYifQDQ5NT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:11.369Z' - }, - { - test: { - id: 'ZDJkYeyIyIjoiMjYifQzRkYj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:11.450Z' - } - ] - } - ] - }, - { - id: '9', - metrics: { - testsCount: 18, - supportLevel: 'FULL', - conflictsCount: 0, - supportPercent: 100, - testsFailedCount: 16, - testsPassedCount: 2, - shouldFormatted: false, - mustFormatted: '16 of 16 passed', - shouldAssertionsCount: 0, - mustAssertionsCount: 16, - unexpectedBehaviorCount: 0, - unexpectedBehaviorsFormatted: false, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 16 - }, - markedFinalAt: null, - isFinal: false, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '9' - }, - testResults: [ - { - test: { - id: 'MThhNeyIyIjoiMjYifQmEyMj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:11.059Z' - }, - { - test: { - id: 'ODY5MeyIyIjoiMjYifQzhmNW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:11.137Z' - }, - { - test: { - id: 'NWVkNeyIyIjoiMjYifQTZkOT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:11.218Z' - } - ] - } - ] - }, - { - id: '3', - metrics: { - testsCount: 18, - supportLevel: 'FAILING', - conflictsCount: 0, - supportPercent: 88, - testsFailedCount: 16, - testsPassedCount: 2, - shouldFormatted: false, - mustFormatted: '14 of 16 passed', - shouldAssertionsCount: 0, - mustAssertionsCount: 16, - unexpectedBehaviorCount: 1, - unexpectedBehaviorsFormatted: '1 found', - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 0, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 14 - }, - markedFinalAt: '2022-07-06T00:00:00.000Z', - isFinal: true, - at: { - id: '1', - key: 'jaws', - name: 'JAWS' - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '3' - }, - testResults: [ - { - test: { - id: 'MThhNeyIyIjoiMjYifQmEyMj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.074Z' - }, - { - test: { - id: 'NWVkNeyIyIjoiMjYifQTZkOT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.134Z' - }, - { - test: { - id: 'NWM4NeyIyIjoiMjYifQDEwM2' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.202Z' - }, - { - test: { - id: 'NGFiZeyIyIjoiMjYifQWZiYW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.268Z' - }, - { - test: { - id: 'MzQzYeyIyIjoiMjYifQzU5Zm' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.336Z' - } - ] - } - ] - }, - { - id: '11', - metrics: { - testsCount: 11, - supportLevel: 'FULL', - conflictsCount: 0, - supportPercent: 100, - testsFailedCount: 9, - testsPassedCount: 2, - shouldFormatted: false, - mustFormatted: '14 of 14 passed', - shouldAssertionsCount: 0, - mustAssertionsCount: 14, - unexpectedBehaviorCount: 0, - unexpectedBehaviorsFormatted: false, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 14 - }, - markedFinalAt: null, - isFinal: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS' - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '11' - }, - testResults: [ - { - test: { - id: 'MzlmYeyIyIjoiMjYifQzIxY2' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:11.532Z' - }, - { - test: { - id: 'N2FkZeyIyIjoiMjYifQDQ5NT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:11.611Z' - }, - { - test: { - id: 'ZDJkYeyIyIjoiMjYifQzRkYj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:11.696Z' - } - ] - } - ] - }, - { - id: '4', - metrics: { - testsCount: 18, - supportLevel: 'FAILING', - conflictsCount: 0, - supportPercent: 91, - testsFailedCount: 14, - testsPassedCount: 4, - shouldFormatted: false, - mustFormatted: '20 of 22 passed', - shouldAssertionsCount: 0, - mustAssertionsCount: 22, - unexpectedBehaviorCount: 1, - unexpectedBehaviorsFormatted: '1 found', - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 0, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 20 - }, - markedFinalAt: '2022-07-06T00:00:00.000Z', - isFinal: true, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '4' - }, - testResults: [ - { - test: { - id: 'MThhNeyIyIjoiMjYifQmEyMj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.409Z' - }, - { - test: { - id: 'NWVkNeyIyIjoiMjYifQTZkOT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.478Z' - }, - { - test: { - id: 'NWM4NeyIyIjoiMjYifQDEwM2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.551Z' - }, - { - test: { - id: 'NGFiZeyIyIjoiMjYifQWZiYW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.629Z' - }, - { - test: { - id: 'MzQzYeyIyIjoiMjYifQzU5Zm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.704Z' - }, - { - test: { - id: 'MmI1MeyIyIjoiMjYifQmU3Yz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.777Z' - }, - { - test: { - id: 'YmRmYeyIyIjoiMjYifQjEyMT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2023-08-18T03:17:09.852Z' - } - ] - } - ] - }, - { - id: '5', - metrics: { - testsCount: 11, - supportLevel: 'FAILING', - conflictsCount: 0, - supportPercent: 92, - testsFailedCount: 8, - testsPassedCount: 3, - shouldFormatted: false, - mustFormatted: '23 of 25 passed', - shouldAssertionsCount: 0, - mustAssertionsCount: 25, - unexpectedBehaviorCount: 1, - unexpectedBehaviorsFormatted: '1 found', - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 0, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 23 - }, - markedFinalAt: '2022-07-06T00:00:00.000Z', - isFinal: true, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS' - }, - browser: { - id: '3', - key: 'safari_macos', - name: 'Safari' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '5' - }, - testResults: [ - { - test: { - id: 'MzlmYeyIyIjoiMjYifQzIxY2' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:09.923Z' - }, - { - test: { - id: 'ZDJkYeyIyIjoiMjYifQzRkYj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:09.991Z' - }, - { - test: { - id: 'ZmQyNeyIyIjoiMjYifQ2M2ND' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.059Z' - }, - { - test: { - id: 'OGE3YeyIyIjoiMjYifQjU1ND' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.129Z' - }, - { - test: { - id: 'YWI3OeyIyIjoiMjYifQWJlNW' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.198Z' - }, - { - test: { - id: 'M2RiOeyIyIjoiMjYifQGY1Nj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2023-08-18T03:17:10.272Z' - } - ] - } - ] - }, - { - id: '8', - metrics: { - testsCount: 18, - supportLevel: 'FULL', - conflictsCount: 0, - supportPercent: 100, - testsFailedCount: 16, - testsPassedCount: 2, - shouldFormatted: false, - mustFormatted: '16 of 16 passed', - shouldAssertionsCount: 0, - mustAssertionsCount: 16, - unexpectedBehaviorCount: 0, - unexpectedBehaviorsFormatted: false, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 16 - }, - markedFinalAt: null, - isFinal: false, - at: { - id: '1', - key: 'jaws', - name: 'JAWS' - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '8' - }, - testResults: [ - { - test: { - id: 'MThhNeyIyIjoiMjYifQmEyMj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:10.817Z' - }, - { - test: { - id: 'ODY5MeyIyIjoiMjYifQzhmNW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:10.894Z' - }, - { - test: { - id: 'NWVkNeyIyIjoiMjYifQTZkOT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2023-08-18T03:17:10.979Z' - } - ] - } - ] - } - ], - metadata: {} - } - ] - } - } - }, - { - request: { - query: testPlanReportStatusDialogQuery, - variables: { testPlanVersionId: '1' } - }, - result: { - data: { - testPlanVersion: { - id: '1', - title: 'Alert Example', - phase: 'DRAFT', - gitSha: 'c665367f3742c2b607f7b3c2655782188b93f302', - gitMessage: - 'Create updated tests for APG design pattern example: Alert (#685)', - updatedAt: '2022-04-14T17:59:42.000Z', - draftPhaseReachedAt: '2022-07-06T00:00:00.000Z', - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'alert' - }, - testPlanReportStatuses: [ - { - isRequired: true, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '101', - metrics: {}, - isFinal: false, - markedFinalAt: null, - issues: [], - draftTestPlanRuns: [] - } - }, - { - isRequired: false, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'chrome', - name: 'Firefox' - }, - minimumAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: true, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: false, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: true, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '3', - key: 'safari_macos', - name: 'Safari' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '7', - metrics: {}, - isFinal: false, - markedFinalAt: null, - issues: [], - draftTestPlanRuns: [] - } - } - ] - } - } - } - }, - { - request: { - query: testPlanReportStatusDialogQuery, - variables: { testPlanVersionId: '5' } - }, - result: { - data: { - testPlanVersion: { - id: '69', - title: 'Checkbox Example (Mixed-State)', - phase: 'RECOMMENDED', - gitSha: '836fb2a997f5b2844035b8c934f8fda9833cd5b2', - gitMessage: 'Validation for test csv formats (#980)', - updatedAt: '2023-08-23T20:30:34.000Z', - draftPhaseReachedAt: null, - candidatePhaseReachedAt: '2022-07-06T00:00:00.000Z', - recommendedPhaseTargetDate: '2023-01-02T00:00:00.000Z', - recommendedPhaseReachedAt: '2023-01-03T00:00:00.000Z', - testPlan: { - directory: 'checkbox-tri-state' - }, - testPlanReportStatuses: [ - { - isRequired: true, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '12', - metrics: { - testsCount: 14, - mayFormatted: false, - supportLevel: 'FULL', - commandsCount: 26, - mustFormatted: '116 of 116 passed', - conflictsCount: 0, - supportPercent: 100, - shouldFormatted: '34 of 34 passed', - testsFailedCount: 0, - testsPassedCount: 14, - mayAssertionsCount: 0, - mustAssertionsCount: 116, - assertionsFailedCount: 0, - assertionsPassedCount: 150, - shouldAssertionsCount: 34, - unexpectedBehaviorCount: 0, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 116, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 34, - unexpectedBehaviorsFormatted: false, - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 26, - moderateImpactFailedAssertionCount: 0, - moderateImpactPassedAssertionCount: 26 - }, - isFinal: true, - markedFinalAt: '2022-07-06T00:00:00.000Z', - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '12' - }, - testResults: [ - { - test: { - id: 'YWYzOeyIyIjoiNjkifQTQ0MT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:52.053Z' - }, - { - test: { - id: 'OGZjNeyIyIjoiNjkifQjQxZW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:52.149Z' - }, - { - test: { - id: 'NjM3ZeyIyIjoiNjkifQmUxYz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:52.242Z' - }, - { - test: { - id: 'ZWQ0MeyIyIjoiNjkifQGZhYT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:52.321Z' - }, - { - test: { - id: 'ZGI3ZeyIyIjoiNjkifQTc5Mj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:52.409Z' - }, - { - test: { - id: 'MDZjOeyIyIjoiNjkifQGJkYz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:52.510Z' - }, - { - test: { - id: 'ZmI3NeyIyIjoiNjkifQzUwMT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:52.614Z' - }, - { - test: { - id: 'NmY2YeyIyIjoiNjkifQTczOW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:52.731Z' - }, - { - test: { - id: 'MjIwYeyIyIjoiNjkifQmUzZj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:52.882Z' - }, - { - test: { - id: 'ODg0OeyIyIjoiNjkifQWFlYm' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:53.038Z' - }, - { - test: { - id: 'ZDQ2MeyIyIjoiNjkifQjlmZj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:53.184Z' - }, - { - test: { - id: 'MjdlYeyIyIjoiNjkifQTgyNj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:53.317Z' - }, - { - test: { - id: 'OGE5MeyIyIjoiNjkifQGZjOT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:53.428Z' - }, - { - test: { - id: 'YWNlNeyIyIjoiNjkifQjQzOW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:53.567Z' - } - ] - } - ] - } - }, - { - isRequired: true, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: true, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '13', - metrics: { - testsCount: 14, - mayFormatted: false, - supportLevel: 'FULL', - commandsCount: 28, - mustFormatted: '124 of 124 passed', - conflictsCount: 0, - supportPercent: 100, - shouldFormatted: '36 of 36 passed', - testsFailedCount: 0, - testsPassedCount: 14, - mayAssertionsCount: 0, - mustAssertionsCount: 124, - assertionsFailedCount: 0, - assertionsPassedCount: 160, - shouldAssertionsCount: 36, - unexpectedBehaviorCount: 0, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 124, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 36, - unexpectedBehaviorsFormatted: false, - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 28, - moderateImpactFailedAssertionCount: 0, - moderateImpactPassedAssertionCount: 28 - }, - isFinal: true, - markedFinalAt: '2022-07-07T00:00:00.000Z', - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '13' - }, - testResults: [ - { - test: { - id: 'YWYzOeyIyIjoiNjkifQTQ0MT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:53.698Z' - }, - { - test: { - id: 'OGZjNeyIyIjoiNjkifQjQxZW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:53.814Z' - }, - { - test: { - id: 'NjM3ZeyIyIjoiNjkifQmUxYz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:53.921Z' - }, - { - test: { - id: 'ZWQ0MeyIyIjoiNjkifQGZhYT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:54.038Z' - }, - { - test: { - id: 'ZGI3ZeyIyIjoiNjkifQTc5Mj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:54.181Z' - }, - { - test: { - id: 'MDZjOeyIyIjoiNjkifQGJkYz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:54.327Z' - }, - { - test: { - id: 'ZmI3NeyIyIjoiNjkifQzUwMT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:54.421Z' - }, - { - test: { - id: 'NmY2YeyIyIjoiNjkifQTczOW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:54.541Z' - }, - { - test: { - id: 'MjIwYeyIyIjoiNjkifQmUzZj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:54.666Z' - }, - { - test: { - id: 'ODg0OeyIyIjoiNjkifQWFlYm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:54.794Z' - }, - { - test: { - id: 'ZDQ2MeyIyIjoiNjkifQjlmZj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:54.881Z' - }, - { - test: { - id: 'MjdlYeyIyIjoiNjkifQTgyNj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:54.967Z' - }, - { - test: { - id: 'OGE5MeyIyIjoiNjkifQGZjOT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:55.059Z' - }, - { - test: { - id: 'YWNlNeyIyIjoiNjkifQjQzOW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:55.140Z' - } - ] - } - ] - } - }, - { - isRequired: true, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: true, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: true, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '3', - key: 'safari_macos', - name: 'Safari' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '6', - metrics: { - testsCount: 7, - mayFormatted: false, - supportLevel: 'FAILING', - commandsCount: 16, - mustFormatted: '66 of 68 passed', - conflictsCount: 0, - supportPercent: 97, - shouldFormatted: '20 of 20 passed', - testsFailedCount: 2, - testsPassedCount: 5, - mayAssertionsCount: 0, - mustAssertionsCount: 68, - assertionsFailedCount: 2, - assertionsPassedCount: 86, - shouldAssertionsCount: 20, - unexpectedBehaviorCount: 0, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 66, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 20, - unexpectedBehaviorsFormatted: false, - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 16, - moderateImpactFailedAssertionCount: 0, - moderateImpactPassedAssertionCount: 16 - }, - isFinal: true, - markedFinalAt: '2022-07-06T00:00:00.000Z', - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'tom-proudfeet' - }, - testPlanReport: { - id: '6' - }, - testResults: [ - { - test: { - id: 'NmUzMeyIyIjoiNjkifQmU0OT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:45.554Z' - }, - { - test: { - id: 'Y2UyYeyIyIjoiNjkifQ2Y1Mz' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:45.671Z' - }, - { - test: { - id: 'ODc2OeyIyIjoiNjkifQTA1Yz' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:45.794Z' - }, - { - test: { - id: 'OTgwZeyIyIjoiNjkifQDZjOG' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:45.909Z' - }, - { - test: { - id: 'ODA3ZeyIyIjoiNjkifQjI4Y2' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:45.997Z' - }, - { - test: { - id: 'OWI4MeyIyIjoiNjkifQzFlZD' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:46.091Z' - }, - { - test: { - id: 'MzhiZeyIyIjoiNjkifQWE4Nj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:46.189Z' - } - ] - } - ] - } - }, - { - isRequired: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - } - ] - } - } - } - }, - { - request: { - query: testPlanReportStatusDialogQuery, - variables: { testPlanVersionId: '7' } - }, - result: { - data: { - testPlanVersion: { - id: '7', - title: 'Select Only Combobox Example', - phase: 'DRAFT', - gitSha: '7c4b5dce23c74fcf280ed164bdb903e02e0e7726', - gitMessage: - 'Generate html source script to support aria-at-app (#646)', - updatedAt: '2022-03-17T18:34:51.000Z', - draftPhaseReachedAt: '2022-07-06T00:00:00.000Z', - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'combobox-select-only' - }, - testPlanReportStatuses: [ - { - isRequired: true, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: false, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: true, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: false, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '2', - metrics: { - testsCount: 21, - mayFormatted: false, - supportLevel: 'FAILING', - commandsCount: 24, - mustFormatted: '118 of 122 passed', - conflictsCount: 3, - supportPercent: 97, - shouldFormatted: '34 of 36 passed', - testsFailedCount: 6, - testsPassedCount: 15, - mayAssertionsCount: 0, - mustAssertionsCount: 122, - assertionsFailedCount: 6, - assertionsPassedCount: 152, - shouldAssertionsCount: 36, - unexpectedBehaviorCount: 3, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 4, - mustAssertionsPassedCount: 118, - shouldAssertionsFailedCount: 2, - shouldAssertionsPassedCount: 34, - unexpectedBehaviorsFormatted: '3 found', - severeImpactFailedAssertionCount: 1, - severeImpactPassedAssertionCount: 23, - moderateImpactFailedAssertionCount: 2, - moderateImpactPassedAssertionCount: 22 - }, - isFinal: false, - markedFinalAt: null, - issues: [ - { - link: 'https://github.com/bocoup/aria-at/issues/128#issue-2157878584', - isOpen: true, - feedbackType: 'FEEDBACK' - } - ], - draftTestPlanRuns: [ - { - tester: { - username: 'tom-proudfeet' - }, - testPlanReport: { - id: '2' - }, - testResults: [ - { - test: { - id: 'Nzg5NeyIyIjoiNyJ9zNjZj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:38.949Z' - }, - { - test: { - id: 'MmY0YeyIyIjoiNyJ9jRkZD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:39.070Z' - }, - { - test: { - id: 'ZjUwNeyIyIjoiNyJ9mE2ZT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:39.180Z' - }, - { - test: { - id: 'MDNiMeyIyIjoiNyJ9Dk1MT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:39.292Z' - }, - { - test: { - id: 'MjRmNeyIyIjoiNyJ92MyMT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:39.406Z' - }, - { - test: { - id: 'ZmVlMeyIyIjoiNyJ9mUyYj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: null - }, - { - test: { - id: 'YWFiNeyIyIjoiNyJ9zE2Zj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:39.640Z' - }, - { - test: { - id: 'YjZkYeyIyIjoiNyJ9WIxZm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:39.761Z' - }, - { - test: { - id: 'ZmIzMeyIyIjoiNyJ9TQ1NW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:39.888Z' - }, - { - test: { - id: 'MmZkNeyIyIjoiNyJ9zIwN2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:40.006Z' - }, - { - test: { - id: 'ZmQwOeyIyIjoiNyJ9DEzYz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:40.122Z' - }, - { - test: { - id: 'MGViNeyIyIjoiNyJ9GQ3MT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:40.234Z' - }, - { - test: { - id: 'YTg5MeyIyIjoiNyJ9WEzOT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:40.355Z' - }, - { - test: { - id: 'NTRjMeyIyIjoiNyJ9zQ0OD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:40.467Z' - }, - { - test: { - id: 'MjRlZeyIyIjoiNyJ9DcyY2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:40.588Z' - }, - { - test: { - id: 'YWQzNeyIyIjoiNyJ9mE2Nm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:40.712Z' - }, - { - test: { - id: 'OTYxOeyIyIjoiNyJ9TdmYj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:40.826Z' - }, - { - test: { - id: 'MjgzNeyIyIjoiNyJ9TZjNz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:40.948Z' - }, - { - test: { - id: 'NWNiZeyIyIjoiNyJ9jI2MD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:41.075Z' - } - ] - }, - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '2' - }, - testResults: [ - { - test: { - id: 'Nzg5NeyIyIjoiNyJ9zNjZj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:36.666Z' - }, - { - test: { - id: 'MmY0YeyIyIjoiNyJ9jRkZD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:36.793Z' - }, - { - test: { - id: 'ZjUwNeyIyIjoiNyJ9mE2ZT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:36.914Z' - }, - { - test: { - id: 'MDNiMeyIyIjoiNyJ9Dk1MT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:37.031Z' - }, - { - test: { - id: 'MjRmNeyIyIjoiNyJ92MyMT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:37.150Z' - }, - { - test: { - id: 'ZmVlMeyIyIjoiNyJ9mUyYj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: null - }, - { - test: { - id: 'YWFiNeyIyIjoiNyJ9zE2Zj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:37.384Z' - }, - { - test: { - id: 'YjZkYeyIyIjoiNyJ9WIxZm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:37.512Z' - }, - { - test: { - id: 'ZmIzMeyIyIjoiNyJ9TQ1NW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:37.638Z' - }, - { - test: { - id: 'MmZkNeyIyIjoiNyJ9zIwN2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:37.760Z' - }, - { - test: { - id: 'ZmQwOeyIyIjoiNyJ9DEzYz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:37.883Z' - }, - { - test: { - id: 'MGViNeyIyIjoiNyJ9GQ3MT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:38.014Z' - }, - { - test: { - id: 'YTg5MeyIyIjoiNyJ9WEzOT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:38.145Z' - }, - { - test: { - id: 'NTRjMeyIyIjoiNyJ9zQ0OD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:38.268Z' - }, - { - test: { - id: 'MjRlZeyIyIjoiNyJ9DcyY2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:38.382Z' - }, - { - test: { - id: 'YWQzNeyIyIjoiNyJ9mE2Nm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:38.481Z' - }, - { - test: { - id: 'OTYxOeyIyIjoiNyJ9TdmYj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:38.596Z' - }, - { - test: { - id: 'MjgzNeyIyIjoiNyJ9TZjNz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:38.701Z' - }, - { - test: { - id: 'NWNiZeyIyIjoiNyJ9jI2MD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:38.811Z' - } - ] - } - ] - } - }, - { - isRequired: true, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '3', - key: 'safari_macos', - name: 'Safari' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - } - ] - } - } - } - }, - { - request: { - query: testPlanReportStatusDialogQuery, - variables: { testPlanVersionId: '26' } - }, - result: { - data: { - testPlanVersion: { - id: '24', - title: 'Modal Dialog Example', - phase: 'CANDIDATE', - gitSha: '5fe7afd82fe51c185b8661276105190a59d47322', - gitMessage: 'Task 7: delete incorrect instructions (#733)', - updatedAt: '2022-05-26T16:10:10.000Z', - draftPhaseReachedAt: '2022-07-06T00:00:00.000Z', - candidatePhaseReachedAt: '2022-07-06T00:00:00.000Z', - recommendedPhaseTargetDate: '2023-01-02T00:00:00.000Z', - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'modal-dialog' - }, - testPlanReportStatuses: [ - { - isRequired: true, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '3', - metrics: { - testsCount: 18, - mayFormatted: false, - supportLevel: 'FAILING', - commandsCount: 26, - mustFormatted: '115 of 117 passed', - conflictsCount: 0, - supportPercent: 98, - shouldFormatted: '25 of 26 passed', - testsFailedCount: 2, - testsPassedCount: 16, - mayAssertionsCount: 0, - mustAssertionsCount: 117, - assertionsFailedCount: 3, - assertionsPassedCount: 140, - shouldAssertionsCount: 26, - unexpectedBehaviorCount: 1, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 115, - shouldAssertionsFailedCount: 1, - shouldAssertionsPassedCount: 25, - unexpectedBehaviorsFormatted: '1 found', - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 26, - moderateImpactFailedAssertionCount: 1, - moderateImpactPassedAssertionCount: 25 - }, - isFinal: true, - markedFinalAt: '2022-07-06T00:00:00.000Z', - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '3' - }, - testResults: [ - { - test: { - id: 'ZjE0NeyIyIjoiMjQifQmI0NT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:41.177Z' - }, - { - test: { - id: 'YjZlNeyIyIjoiMjQifQTc5ZW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:41.256Z' - }, - { - test: { - id: 'NWM0MeyIyIjoiMjQifQzhiYz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:41.349Z' - }, - { - test: { - id: 'YzM0ZeyIyIjoiMjQifQmRmMz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:41.419Z' - }, - { - test: { - id: 'ZjVjMeyIyIjoiMjQifQDRhY2' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:41.496Z' - }, - { - test: { - id: 'YmUzMeyIyIjoiMjQifQmRmNm' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:41.574Z' - }, - { - test: { - id: 'ZGJmMeyIyIjoiMjQifQzU5Yz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:41.661Z' - }, - { - test: { - id: 'Nzg1OeyIyIjoiMjQifQTYxM2' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:41.741Z' - }, - { - test: { - id: 'ZTI0MeyIyIjoiMjQifQzM4YT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:41.823Z' - }, - { - test: { - id: 'MzY5ZeyIyIjoiMjQifQmQ0OT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:41.950Z' - }, - { - test: { - id: 'ZjVmYeyIyIjoiMjQifQjJjYW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.044Z' - }, - { - test: { - id: 'ZTMwNeyIyIjoiMjQifQzI5Nz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.112Z' - }, - { - test: { - id: 'NGY0MeyIyIjoiMjQifQ2FjMj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.191Z' - }, - { - test: { - id: 'OTI0OeyIyIjoiMjQifQTU1ZT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.271Z' - }, - { - test: { - id: 'MDRhMeyIyIjoiMjQifQWEzMj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.344Z' - }, - { - test: { - id: 'ZThlZeyIyIjoiMjQifQjQ2Nz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.412Z' - }, - { - test: { - id: 'NjhjMeyIyIjoiMjQifQGE0ND' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.482Z' - }, - { - test: { - id: 'YTAzZeyIyIjoiMjQifQTc5ZD' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.575Z' - } - ] - } - ] - } - }, - { - isRequired: false, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: null, - exactAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - testPlanReport: { - id: '105', - metrics: {}, - isFinal: false, - markedFinalAt: null, - issues: [], - draftTestPlanRuns: [] - } - }, - { - isRequired: false, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '8', - metrics: { - testsCount: 18, - mayFormatted: false, - supportLevel: 'FULL', - commandsCount: 26, - mustFormatted: '117 of 117 passed', - conflictsCount: 0, - supportPercent: 100, - shouldFormatted: '26 of 26 passed', - testsFailedCount: 0, - testsPassedCount: 18, - mayAssertionsCount: 0, - mustAssertionsCount: 117, - assertionsFailedCount: 0, - assertionsPassedCount: 143, - shouldAssertionsCount: 26, - unexpectedBehaviorCount: 0, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 117, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 26, - unexpectedBehaviorsFormatted: false, - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 26, - moderateImpactFailedAssertionCount: 0, - moderateImpactPassedAssertionCount: 26 - }, - isFinal: false, - markedFinalAt: null, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '8' - }, - testResults: [ - { - test: { - id: 'ZjE0NeyIyIjoiMjQifQmI0NT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:46.300Z' - }, - { - test: { - id: 'YjZlNeyIyIjoiMjQifQTc5ZW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:46.396Z' - }, - { - test: { - id: 'NWM0MeyIyIjoiMjQifQzhiYz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:46.490Z' - }, - { - test: { - id: 'YzM0ZeyIyIjoiMjQifQmRmMz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:46.572Z' - }, - { - test: { - id: 'ZjVjMeyIyIjoiMjQifQDRhY2' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:46.656Z' - }, - { - test: { - id: 'YmUzMeyIyIjoiMjQifQmRmNm' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:46.743Z' - }, - { - test: { - id: 'ZGJmMeyIyIjoiMjQifQzU5Yz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:46.828Z' - }, - { - test: { - id: 'Nzg1OeyIyIjoiMjQifQTYxM2' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:46.912Z' - }, - { - test: { - id: 'ZTI0MeyIyIjoiMjQifQzM4YT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:46.990Z' - }, - { - test: { - id: 'MzY5ZeyIyIjoiMjQifQmQ0OT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:47.087Z' - }, - { - test: { - id: 'ZjVmYeyIyIjoiMjQifQjJjYW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:47.215Z' - }, - { - test: { - id: 'ZTMwNeyIyIjoiMjQifQzI5Nz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:47.355Z' - }, - { - test: { - id: 'NGY0MeyIyIjoiMjQifQ2FjMj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:47.484Z' - }, - { - test: { - id: 'OTI0OeyIyIjoiMjQifQTU1ZT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:47.614Z' - }, - { - test: { - id: 'MDRhMeyIyIjoiMjQifQWEzMj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:47.738Z' - }, - { - test: { - id: 'ZThlZeyIyIjoiMjQifQjQ2Nz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:47.862Z' - }, - { - test: { - id: 'NjhjMeyIyIjoiMjQifQGE0ND' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:47.981Z' - }, - { - test: { - id: 'YTAzZeyIyIjoiMjQifQTc5ZD' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:48.105Z' - } - ] - } - ] - } - }, - { - isRequired: true, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '4', - metrics: { - testsCount: 18, - mayFormatted: false, - supportLevel: 'FAILING', - commandsCount: 26, - mustFormatted: '115 of 117 passed', - conflictsCount: 0, - supportPercent: 98, - shouldFormatted: '25 of 26 passed', - testsFailedCount: 2, - testsPassedCount: 16, - mayAssertionsCount: 0, - mustAssertionsCount: 117, - assertionsFailedCount: 3, - assertionsPassedCount: 140, - shouldAssertionsCount: 26, - unexpectedBehaviorCount: 1, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 115, - shouldAssertionsFailedCount: 1, - shouldAssertionsPassedCount: 25, - unexpectedBehaviorsFormatted: '1 found', - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 26, - moderateImpactFailedAssertionCount: 1, - moderateImpactPassedAssertionCount: 25 - }, - isFinal: true, - markedFinalAt: '2022-07-06T00:00:00.000Z', - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '4' - }, - testResults: [ - { - test: { - id: 'ZjE0NeyIyIjoiMjQifQmI0NT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.683Z' - }, - { - test: { - id: 'YjZlNeyIyIjoiMjQifQTc5ZW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.772Z' - }, - { - test: { - id: 'NWM0MeyIyIjoiMjQifQzhiYz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.848Z' - }, - { - test: { - id: 'YzM0ZeyIyIjoiMjQifQmRmMz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:42.928Z' - }, - { - test: { - id: 'ZjVjMeyIyIjoiMjQifQDRhY2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.005Z' - }, - { - test: { - id: 'YmUzMeyIyIjoiMjQifQmRmNm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.093Z' - }, - { - test: { - id: 'ZGJmMeyIyIjoiMjQifQzU5Yz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.173Z' - }, - { - test: { - id: 'Nzg1OeyIyIjoiMjQifQTYxM2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.245Z' - }, - { - test: { - id: 'ZTI0MeyIyIjoiMjQifQzM4YT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.318Z' - }, - { - test: { - id: 'MzY5ZeyIyIjoiMjQifQmQ0OT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.399Z' - }, - { - test: { - id: 'ZjVmYeyIyIjoiMjQifQjJjYW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.473Z' - }, - { - test: { - id: 'ZTMwNeyIyIjoiMjQifQzI5Nz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.554Z' - }, - { - test: { - id: 'NGY0MeyIyIjoiMjQifQ2FjMj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.643Z' - }, - { - test: { - id: 'OTI0OeyIyIjoiMjQifQTU1ZT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.738Z' - }, - { - test: { - id: 'MDRhMeyIyIjoiMjQifQWEzMj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.844Z' - }, - { - test: { - id: 'ZThlZeyIyIjoiMjQifQjQ2Nz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:43.950Z' - }, - { - test: { - id: 'NjhjMeyIyIjoiMjQifQGE0ND' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:44.078Z' - }, - { - test: { - id: 'YTAzZeyIyIjoiMjQifQTc5ZD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:44.219Z' - } - ] - } - ] - } - }, - { - isRequired: false, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '9', - metrics: { - testsCount: 18, - mayFormatted: false, - supportLevel: 'FULL', - commandsCount: 26, - mustFormatted: '117 of 117 passed', - conflictsCount: 0, - supportPercent: 100, - shouldFormatted: '26 of 26 passed', - testsFailedCount: 0, - testsPassedCount: 18, - mayAssertionsCount: 0, - mustAssertionsCount: 117, - assertionsFailedCount: 0, - assertionsPassedCount: 143, - shouldAssertionsCount: 26, - unexpectedBehaviorCount: 0, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 117, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 26, - unexpectedBehaviorsFormatted: false, - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 26, - moderateImpactFailedAssertionCount: 0, - moderateImpactPassedAssertionCount: 26 - }, - isFinal: false, - markedFinalAt: null, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '9' - }, - testResults: [ - { - test: { - id: 'ZjE0NeyIyIjoiMjQifQmI0NT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:48.229Z' - }, - { - test: { - id: 'YjZlNeyIyIjoiMjQifQTc5ZW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:48.339Z' - }, - { - test: { - id: 'NWM0MeyIyIjoiMjQifQzhiYz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:48.439Z' - }, - { - test: { - id: 'YzM0ZeyIyIjoiMjQifQmRmMz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:48.537Z' - }, - { - test: { - id: 'ZjVjMeyIyIjoiMjQifQDRhY2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:48.636Z' - }, - { - test: { - id: 'YmUzMeyIyIjoiMjQifQmRmNm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:48.736Z' - }, - { - test: { - id: 'ZGJmMeyIyIjoiMjQifQzU5Yz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:48.824Z' - }, - { - test: { - id: 'Nzg1OeyIyIjoiMjQifQTYxM2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:48.901Z' - }, - { - test: { - id: 'ZTI0MeyIyIjoiMjQifQzM4YT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:48.978Z' - }, - { - test: { - id: 'MzY5ZeyIyIjoiMjQifQmQ0OT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:49.070Z' - }, - { - test: { - id: 'ZjVmYeyIyIjoiMjQifQjJjYW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:49.161Z' - }, - { - test: { - id: 'ZTMwNeyIyIjoiMjQifQzI5Nz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:49.264Z' - }, - { - test: { - id: 'NGY0MeyIyIjoiMjQifQ2FjMj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:49.387Z' - }, - { - test: { - id: 'OTI0OeyIyIjoiMjQifQTU1ZT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:49.527Z' - }, - { - test: { - id: 'MDRhMeyIyIjoiMjQifQWEzMj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:49.646Z' - }, - { - test: { - id: 'ZThlZeyIyIjoiMjQifQjQ2Nz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:49.747Z' - }, - { - test: { - id: 'NjhjMeyIyIjoiMjQifQGE0ND' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:49.847Z' - }, - { - test: { - id: 'YTAzZeyIyIjoiMjQifQTc5ZD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:49.951Z' - } - ] - } - ] - } - }, - { - isRequired: true, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '3', - key: 'safari_macos', - name: 'Safari' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '5', - metrics: { - testsCount: 11, - mayFormatted: false, - supportLevel: 'FAILING', - commandsCount: 20, - mustFormatted: '88 of 90 passed', - conflictsCount: 0, - supportPercent: 98, - shouldFormatted: '19 of 20 passed', - testsFailedCount: 2, - testsPassedCount: 9, - mayAssertionsCount: 0, - mustAssertionsCount: 90, - assertionsFailedCount: 3, - assertionsPassedCount: 107, - shouldAssertionsCount: 20, - unexpectedBehaviorCount: 1, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 88, - shouldAssertionsFailedCount: 1, - shouldAssertionsPassedCount: 19, - unexpectedBehaviorsFormatted: '1 found', - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 20, - moderateImpactFailedAssertionCount: 1, - moderateImpactPassedAssertionCount: 19 - }, - isFinal: true, - markedFinalAt: '2022-07-06T00:00:00.000Z', - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '5' - }, - testResults: [ - { - test: { - id: 'NjM0MeyIyIjoiMjQifQTdiZG' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:44.402Z' - }, - { - test: { - id: 'YWYzOeyIyIjoiMjQifQDBjN2' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:44.489Z' - }, - { - test: { - id: 'ZmJjYeyIyIjoiMjQifQWJiNT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:44.594Z' - }, - { - test: { - id: 'MjU2NeyIyIjoiMjQifQTk2YW' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:44.694Z' - }, - { - test: { - id: 'MWNlNeyIyIjoiMjQifQTRhNT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:44.781Z' - }, - { - test: { - id: 'YzFlYeyIyIjoiMjQifQjE5Yj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:44.877Z' - }, - { - test: { - id: 'N2UwMeyIyIjoiMjQifQTQ1OT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:44.966Z' - }, - { - test: { - id: 'OTYwOeyIyIjoiMjQifQTE3ND' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:45.061Z' - }, - { - test: { - id: 'OWI2MeyIyIjoiMjQifQmE0ZD' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:45.165Z' - }, - { - test: { - id: 'YTU0MeyIyIjoiMjQifQjNhNj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:45.296Z' - }, - { - test: { - id: 'NTM4MeyIyIjoiMjQifQGVlNm' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:45.433Z' - } - ] - } - ] - } - }, - { - isRequired: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '11', - metrics: { - testsCount: 11, - mayFormatted: false, - supportLevel: 'FULL', - commandsCount: 20, - mustFormatted: '90 of 90 passed', - conflictsCount: 0, - supportPercent: 100, - shouldFormatted: '20 of 20 passed', - testsFailedCount: 0, - testsPassedCount: 11, - mayAssertionsCount: 0, - mustAssertionsCount: 90, - assertionsFailedCount: 0, - assertionsPassedCount: 110, - shouldAssertionsCount: 20, - unexpectedBehaviorCount: 0, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 90, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 20, - unexpectedBehaviorsFormatted: false, - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 20, - moderateImpactFailedAssertionCount: 0, - moderateImpactPassedAssertionCount: 20 - }, - isFinal: false, - markedFinalAt: null, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '11' - }, - testResults: [ - { - test: { - id: 'NjM0MeyIyIjoiMjQifQTdiZG' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.034Z' - }, - { - test: { - id: 'YWYzOeyIyIjoiMjQifQDBjN2' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.120Z' - }, - { - test: { - id: 'ZmJjYeyIyIjoiMjQifQWJiNT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.205Z' - }, - { - test: { - id: 'MjU2NeyIyIjoiMjQifQTk2YW' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.313Z' - }, - { - test: { - id: 'MWNlNeyIyIjoiMjQifQTRhNT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.410Z' - }, - { - test: { - id: 'YzFlYeyIyIjoiMjQifQjE5Yj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.489Z' - }, - { - test: { - id: 'N2UwMeyIyIjoiMjQifQTQ1OT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.561Z' - }, - { - test: { - id: 'OTYwOeyIyIjoiMjQifQTE3ND' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.648Z' - }, - { - test: { - id: 'OWI2MeyIyIjoiMjQifQmE0ZD' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.736Z' - }, - { - test: { - id: 'YTU0MeyIyIjoiMjQifQjNhNj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.832Z' - }, - { - test: { - id: 'NTM4MeyIyIjoiMjQifQGVlNm' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:51.954Z' - } - ] - } - ] - } - }, - { - isRequired: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '10', - metrics: { - testsCount: 11, - mayFormatted: false, - supportLevel: 'FULL', - commandsCount: 20, - mustFormatted: '90 of 90 passed', - conflictsCount: 0, - supportPercent: 100, - shouldFormatted: '20 of 20 passed', - testsFailedCount: 0, - testsPassedCount: 11, - mayAssertionsCount: 0, - mustAssertionsCount: 90, - assertionsFailedCount: 0, - assertionsPassedCount: 110, - shouldAssertionsCount: 20, - unexpectedBehaviorCount: 0, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 90, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 20, - unexpectedBehaviorsFormatted: false, - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 20, - moderateImpactFailedAssertionCount: 0, - moderateImpactPassedAssertionCount: 20 - }, - isFinal: false, - markedFinalAt: null, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '10' - }, - testResults: [ - { - test: { - id: 'NjM0MeyIyIjoiMjQifQTdiZG' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.048Z' - }, - { - test: { - id: 'YWYzOeyIyIjoiMjQifQDBjN2' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.128Z' - }, - { - test: { - id: 'ZmJjYeyIyIjoiMjQifQWJiNT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.203Z' - }, - { - test: { - id: 'MjU2NeyIyIjoiMjQifQTk2YW' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.278Z' - }, - { - test: { - id: 'MWNlNeyIyIjoiMjQifQTRhNT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.355Z' - }, - { - test: { - id: 'YzFlYeyIyIjoiMjQifQjE5Yj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.426Z' - }, - { - test: { - id: 'N2UwMeyIyIjoiMjQifQTQ1OT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.508Z' - }, - { - test: { - id: 'OTYwOeyIyIjoiMjQifQTE3ND' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.591Z' - }, - { - test: { - id: 'OWI2MeyIyIjoiMjQifQmE0ZD' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.687Z' - }, - { - test: { - id: 'YTU0MeyIyIjoiMjQifQjNhNj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.788Z' - }, - { - test: { - id: 'NTM4MeyIyIjoiMjQifQGVlNm' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '1', - name: '99.0.1' - }, - completedAt: '2024-04-25T16:44:50.914Z' - } - ] - } - ] - } - } - ] - } - } - } - }, - { - request: { - query: testPlanReportStatusDialogQuery, - variables: { testPlanVersionId: '34' } - }, - result: { - data: { - testPlanVersion: { - id: '31', - title: 'Toggle Button', - phase: 'DRAFT', - gitSha: '022340081280b8cafb8ae0716a5b67e9ab942ef4', - gitMessage: - 'Delete duplicated assertion for operating a not pressed togle button (VoiceOver) (#716)', - updatedAt: '2022-05-18T20:51:40.000Z', - draftPhaseReachedAt: '2022-07-06T00:00:00.000Z', - candidatePhaseReachedAt: null, - recommendedPhaseTargetDate: null, - recommendedPhaseReachedAt: null, - testPlan: { - directory: 'toggle-button' - }, - testPlanReportStatuses: [ - { - isRequired: true, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '1', - metrics: { - testsCount: 16, - mayFormatted: false, - supportLevel: 'FAILING', - commandsCount: 26, - mustFormatted: '86 of 88 passed', - conflictsCount: 0, - supportPercent: 98, - shouldFormatted: '25 of 26 passed', - testsFailedCount: 6, - testsPassedCount: 10, - mayAssertionsCount: 0, - mustAssertionsCount: 88, - assertionsFailedCount: 3, - assertionsPassedCount: 111, - shouldAssertionsCount: 26, - unexpectedBehaviorCount: 1, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 2, - mustAssertionsPassedCount: 86, - shouldAssertionsFailedCount: 1, - shouldAssertionsPassedCount: 25, - unexpectedBehaviorsFormatted: '1 found', - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 26, - moderateImpactFailedAssertionCount: 1, - moderateImpactPassedAssertionCount: 25 - }, - isFinal: false, - markedFinalAt: null, - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '1' - }, - testResults: [ - { - test: { - id: 'MTExZeyIyIjoiMzEifQWZhZG' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:35.281Z' - }, - { - test: { - id: 'MzJkZeyIyIjoiMzEifQTAzMm' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: null - }, - { - test: { - id: 'NDBjMeyIyIjoiMzEifQjc1NT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: null - }, - { - test: { - id: 'MjE2MeyIyIjoiMzEifQ2M0NW' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: null - }, - { - test: { - id: 'MWZiZeyIyIjoiMzEifQjhhYz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:35.541Z' - }, - { - test: { - id: 'NmI4NeyIyIjoiMzEifQDU2OD' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:35.636Z' - }, - { - test: { - id: 'YmExNeyIyIjoiMzEifQWE5Nj' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:35.730Z' - }, - { - test: { - id: 'YzA3NeyIyIjoiMzEifQGZhYT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:35.831Z' - }, - { - test: { - id: 'YmYxOeyIyIjoiMzEifQDAxY2' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:35.928Z' - }, - { - test: { - id: 'YzIwOeyIyIjoiMzEifQGE2Yz' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:36.034Z' - }, - { - test: { - id: 'YWMwNeyIyIjoiMzEifQDQ5MG' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:36.126Z' - }, - { - test: { - id: 'MjQyMeyIyIjoiMzEifQWExMm' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:36.210Z' - }, - { - test: { - id: 'NDFiYeyIyIjoiMzEifQzg4MD' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:36.332Z' - }, - { - test: { - id: 'M2RmNeyIyIjoiMzEifQzQ0MG' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:36.409Z' - }, - { - test: { - id: 'ODhlYeyIyIjoiMzEifQmVmMT' - }, - atVersion: { - id: '1', - name: '2021.2111.13' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:36.510Z' - } - ] - } - ] - } - }, - { - isRequired: false, - at: { - id: '1', - key: 'jaws', - name: 'JAWS', - atVersions: [ - { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '1', - name: '2021.2111.13', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: true, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '14', - metrics: { - testsCount: 16, - mayFormatted: false, - supportLevel: 'FULL', - commandsCount: 36, - mustFormatted: '128 of 128 passed', - conflictsCount: 0, - supportPercent: 100, - shouldFormatted: '36 of 36 passed', - testsFailedCount: 0, - testsPassedCount: 16, - mayAssertionsCount: 0, - mustAssertionsCount: 128, - assertionsFailedCount: 0, - assertionsPassedCount: 164, - shouldAssertionsCount: 36, - unexpectedBehaviorCount: 0, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 128, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 36, - unexpectedBehaviorsFormatted: false, - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 36, - moderateImpactFailedAssertionCount: 0, - moderateImpactPassedAssertionCount: 36 - }, - isFinal: true, - markedFinalAt: '2022-07-07T00:00:00.000Z', - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '14' - }, - testResults: [ - { - test: { - id: 'MTExZeyIyIjoiMzEifQWZhZG' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:55.237Z' - }, - { - test: { - id: 'MzJkZeyIyIjoiMzEifQTAzMm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:55.347Z' - }, - { - test: { - id: 'NDBjMeyIyIjoiMzEifQjc1NT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:55.423Z' - }, - { - test: { - id: 'MjE2MeyIyIjoiMzEifQ2M0NW' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:55.518Z' - }, - { - test: { - id: 'MmZmNeyIyIjoiMzEifQ2IxOG' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:55.613Z' - }, - { - test: { - id: 'MWZiZeyIyIjoiMzEifQjhhYz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:55.721Z' - }, - { - test: { - id: 'NmI4NeyIyIjoiMzEifQDU2OD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:55.838Z' - }, - { - test: { - id: 'YmExNeyIyIjoiMzEifQWE5Nj' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:55.965Z' - }, - { - test: { - id: 'YzA3NeyIyIjoiMzEifQGZhYT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:56.079Z' - }, - { - test: { - id: 'YmYxOeyIyIjoiMzEifQDAxY2' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:56.177Z' - }, - { - test: { - id: 'YzIwOeyIyIjoiMzEifQGE2Yz' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:56.286Z' - }, - { - test: { - id: 'YWMwNeyIyIjoiMzEifQDQ5MG' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:56.389Z' - }, - { - test: { - id: 'MjQyMeyIyIjoiMzEifQWExMm' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:56.509Z' - }, - { - test: { - id: 'NDFiYeyIyIjoiMzEifQzg4MD' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:56.639Z' - }, - { - test: { - id: 'M2RmNeyIyIjoiMzEifQzQ0MG' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:56.783Z' - }, - { - test: { - id: 'ODhlYeyIyIjoiMzEifQmVmMT' - }, - atVersion: { - id: '2', - name: '2020.4' - }, - browserVersion: { - id: '2', - name: '99.0.4844.84' - }, - completedAt: '2024-04-25T16:44:56.935Z' - } - ] - } - ] - } - }, - { - isRequired: false, - at: { - id: '2', - key: 'nvda', - name: 'NVDA', - atVersions: [ - { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '2', - name: '2020.4', - supportedByAutomation: false, - releasedAt: '2020-04-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: true, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '3', - key: 'safari_macos', - name: 'Safari' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: { - id: '15', - metrics: { - testsCount: 8, - mayFormatted: false, - supportLevel: 'FULL', - commandsCount: 22, - mustFormatted: '76 of 76 passed', - conflictsCount: 0, - supportPercent: 100, - shouldFormatted: '22 of 22 passed', - testsFailedCount: 0, - testsPassedCount: 8, - mayAssertionsCount: 0, - mustAssertionsCount: 76, - assertionsFailedCount: 0, - assertionsPassedCount: 98, - shouldAssertionsCount: 22, - unexpectedBehaviorCount: 0, - mayAssertionsFailedCount: 0, - mayAssertionsPassedCount: 0, - mustAssertionsFailedCount: 0, - mustAssertionsPassedCount: 76, - shouldAssertionsFailedCount: 0, - shouldAssertionsPassedCount: 22, - unexpectedBehaviorsFormatted: false, - severeImpactFailedAssertionCount: 0, - severeImpactPassedAssertionCount: 22, - moderateImpactFailedAssertionCount: 0, - moderateImpactPassedAssertionCount: 22 - }, - isFinal: true, - markedFinalAt: '2022-07-07T00:00:00.000Z', - issues: [], - draftTestPlanRuns: [ - { - tester: { - username: 'esmeralda-baggins' - }, - testPlanReport: { - id: '15' - }, - testResults: [ - { - test: { - id: 'NWUyZeyIyIjoiMzEifQDVkND' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:57.086Z' - }, - { - test: { - id: 'N2I0YeyIyIjoiMzEifQjEwYj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:57.206Z' - }, - { - test: { - id: 'NmZjOeyIyIjoiMzEifQGY5ZT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:57.334Z' - }, - { - test: { - id: 'YmU1MeyIyIjoiMzEifQzBiYj' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:57.464Z' - }, - { - test: { - id: 'MGQyYeyIyIjoiMzEifQzcxZm' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:57.599Z' - }, - { - test: { - id: 'ZmI0YeyIyIjoiMzEifQTU2Nz' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:57.734Z' - }, - { - test: { - id: 'YmRjZeyIyIjoiMzEifQGQyND' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:57.880Z' - }, - { - test: { - id: 'YWFmMeyIyIjoiMzEifQzMwMT' - }, - atVersion: { - id: '3', - name: '11.6 (20G165)' - }, - browserVersion: { - id: '3', - name: '14.1.2' - }, - completedAt: '2024-04-25T16:44:58.035Z' - } - ] - } - ] - } - }, - { - isRequired: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '2', - key: 'chrome', - name: 'Chrome' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - }, - { - isRequired: false, - at: { - id: '3', - key: 'voiceover_macos', - name: 'VoiceOver for macOS', - atVersions: [ - { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - } - ] - }, - browser: { - id: '1', - key: 'firefox', - name: 'Firefox' - }, - minimumAtVersion: { - id: '3', - name: '11.6 (20G165)', - supportedByAutomation: false, - releasedAt: '2021-11-01T04:00:00.000Z' - }, - exactAtVersion: null, - testPlanReport: null - } - ] - } - } - } - } -]; diff --git a/client/tests/__mocks__/GraphQLMocks/index.js b/client/tests/__mocks__/GraphQLMocks/index.js index f2e5142a4..a9b9e9f94 100644 --- a/client/tests/__mocks__/GraphQLMocks/index.js +++ b/client/tests/__mocks__/GraphQLMocks/index.js @@ -1,6 +1,5 @@ import { TEST_QUEUE_PAGE_QUERY } from '@components/TestQueue/queries'; import { TEST_PLAN_REPORT_AT_BROWSER_QUERY } from '@components/common/AssignTesterDropdown/queries'; -import { DATA_MANAGEMENT_PAGE_QUERY } from '@components/DataManagement/queries'; import { TEST_PLAN_REPORT_STATUS_DIALOG_QUERY } from '@components/TestPlanReportStatusDialog/queries'; import { EXISTING_TEST_PLAN_REPORTS } from '@components/AddTestToQueueWithConfirmation/queries'; import { ME_QUERY } from '@components/App/queries'; @@ -8,7 +7,6 @@ import { ME_QUERY } from '@components/App/queries'; import TestQueuePageAdminNotPopulatedMock from './TestQueuePageAdminNotPopulatedMock'; import TestQueuePageTesterNotPopulatedMock from './TestQueuePageTesterNotPopulatedMock'; -import DataManagementPagePopulatedMock from './DataManagementPagePopulatedMock'; import TestPlanReportStatusDialogMock from './TestPlanReportStatusDialogMock'; import TestQueuePageBaseMock from './TestQueuePageBaseMock'; @@ -23,13 +21,6 @@ export const TEST_QUEUE_PAGE_BASE_MOCK_DATA = TestQueuePageBaseMock( EXISTING_TEST_PLAN_REPORTS ); -export const DATA_MANAGEMENT_PAGE_POPULATED_MOCK_DATA = - DataManagementPagePopulatedMock( - ME_QUERY, - DATA_MANAGEMENT_PAGE_QUERY, - TEST_PLAN_REPORT_STATUS_DIALOG_QUERY - ); - export const TEST_PLAN_REPORT_STATUS_DIALOG_MOCK_DATA = TestPlanReportStatusDialogMock( ME_QUERY, diff --git a/client/tests/e2e/CandidateReview.e2e.test.js b/client/tests/e2e/CandidateReview.e2e.test.js new file mode 100644 index 000000000..98c7811c1 --- /dev/null +++ b/client/tests/e2e/CandidateReview.e2e.test.js @@ -0,0 +1,113 @@ +import getPage from '../util/getPage'; +import { text, display } from './util'; + +describe('Candidate Review when not signed in or tester', () => { + it('does not render page if signed out', async () => { + await getPage({ role: false, url: '/candidate-review' }, async page => { + const h1Text = await text(page, 'h1'); + const currentUrl = await page.url(); + + expect(h1Text).toBe('Whoops! Unable to complete request'); + expect(currentUrl.includes('/invalid-request')).toBe(true); + }); + }); + + it('does not render page if tester', async () => { + await getPage({ role: 'tester', url: '/candidate-review' }, async page => { + const h1Text = await text(page, 'h1'); + const currentUrl = await page.url(); + + expect(h1Text).toBe('Whoops! Page not found'); + expect(currentUrl.includes('/404')).toBe(true); + }); + }); +}); + +describe('Candidate Review when signed in as vendor', () => { + it('renders page if signed in', async () => { + await getPage( + { role: 'vendor', url: '/candidate-review' }, + async (page, { consoleErrors }) => { + await page.waitForSelector('h1 ::-p-text(Candidate Review)'); + + // Get section's disclosure titles + await page.waitForSelector('h3 button ::-p-text(JAWS)'); + await page.waitForSelector('h3 button ::-p-text(NVDA)'); + await page.waitForSelector('h3 button ::-p-text(VoiceOver for macOS)'); + + // Check for table headings + await page.waitForSelector('th ::-p-text(Candidate Test Plans)'); + await page.waitForSelector('th ::-p-text(Last Updated)'); + await page.waitForSelector('th ::-p-text(Target Completion Date)'); + await page.waitForSelector('th ::-p-text(Review Status)'); + await page.waitForSelector('th ::-p-text(Results Summary)'); + + await page.waitForSelector('h3 ::-p-text(Review Status Summary)'); + + // Test disclosure collapse interaction + const tableDisclosureContainerSelector = 'div#expand-at-1'; + const initialDisplayForTableDisclosureContainer = await display( + page, + tableDisclosureContainerSelector + ); + await page.click('h3 button ::-p-text(JAWS)'); + const afterClickDisplayForTableDisclosureContainer = await display( + page, + tableDisclosureContainerSelector + ); + + expect(initialDisplayForTableDisclosureContainer).not.toBe('none'); + expect(afterClickDisplayForTableDisclosureContainer).toBe('none'); + + expect(consoleErrors).toHaveLength(0); + } + ); + }); + + it('navigates to candidate test plan run page', async () => { + await getPage({ role: 'vendor', url: '/candidate-review' }, async page => { + await page.waitForSelector('h1 ::-p-text(Candidate Review)'); + + // Select first possible link from the table in the Candidate Test Plans + // column + await page.click('table[aria-label] a'); + + await page.waitForSelector('nav#test-navigator-nav ol'); + await page.waitForSelector('h1 ::-p-text(1.)'); + await page.waitForSelector('h1[class="current-test-title"]'); + + // Expand Test Instructions and Test Results + const instructionsDisclosureContainerSelector = + '[id="disclosure-container-test-instructions-and-results-Test Instructions"]'; + const testResultsDisclosureContainerSelector = + '[id^="disclosure-container-test-instructions-and-results-Test Results for"]'; + const initialInstructionsDisclosureDisplay = await display( + page, + instructionsDisclosureContainerSelector + ); + const initialTestResultDisclosureDisplay = await display( + page, + testResultsDisclosureContainerSelector + ); + + await page.click('button ::-p-text(Test Instructions)'); + await page.click('button ::-p-text(Test Results for)'); + + const afterClickInstructionsDisclosureDisplay = await display( + page, + instructionsDisclosureContainerSelector + ); + const afterClickTestResultDisclosureDisplay = await display( + page, + testResultsDisclosureContainerSelector + ); + + const currentUrl = await page.url(); + expect(currentUrl).toMatch(/^.*\/candidate-test-plan\/\d+\/\d+/); + expect(initialInstructionsDisclosureDisplay).toBe('none'); + expect(initialTestResultDisclosureDisplay).toBe('none'); + expect(afterClickInstructionsDisclosureDisplay).not.toBe('none'); + expect(afterClickTestResultDisclosureDisplay).not.toBe('none'); + }); + }); +}); diff --git a/client/tests/e2e/DataManagement.e2e.test.js b/client/tests/e2e/DataManagement.e2e.test.js new file mode 100644 index 000000000..043a0263a --- /dev/null +++ b/client/tests/e2e/DataManagement.e2e.test.js @@ -0,0 +1,107 @@ +import getPage from '../util/getPage'; +import { text } from './util'; + +describe('Data Management common traits', () => { + it('renders page h1', async () => { + await getPage({ role: false, url: '/data-management' }, async page => { + const h1Element = await text(page, 'h1'); + expect(h1Element).toBe('Data Management'); + }); + }); + + it('renders page with introduction', async () => { + await getPage( + { role: false, url: '/data-management' }, + async (page, { consoleErrors }) => { + const introductionHeadingSelector = 'h2 ::-p-text(Introduction)'; + const introductionHeadingText = await text( + page, + introductionHeadingSelector + ); + expect(introductionHeadingText).toBe('Introduction'); + + expect(consoleErrors).toHaveLength(0); + + const introductionContentSelector = + '[data-testid="data-management-instructions"]'; + const introductionContentText = await text( + page, + introductionContentSelector + ); + + expect(introductionContentText).toMatch( + /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\./ + ); + + expect(consoleErrors).toHaveLength(0); + } + ); + }); + + it('renders page with Test Plan Status Summary heading and table', async () => { + await getPage({ role: false, url: '/data-management' }, async page => { + const testPlansStatusSummarySelector = 'h2 ::-p-text(Test Plans Status)'; + const testPlansStatusSummaryText = await text( + page, + testPlansStatusSummarySelector + ); + + const testPlansStatusSummaryTableSelector = `table[aria-label="${testPlansStatusSummaryText} Table"]`; + await page.waitForSelector(testPlansStatusSummarySelector); + + const tableHeadings = await page.$eval( + testPlansStatusSummaryTableSelector, + el => { + const headings = []; + const headingCells = el.querySelectorAll('thead th'); + headingCells.forEach(cell => headings.push(cell.innerText.trim())); + + return headings; + } + ); + + const tableRowCount = await page.$eval( + testPlansStatusSummaryTableSelector, + el => el.rows.length + ); + + expect(testPlansStatusSummaryText).toBe('Test Plans Status Summary'); + expect(tableHeadings.length).toEqual(7); + expect(tableHeadings.includes('Test Plan')).toBe(true); + expect(tableHeadings.includes('Covered AT')).toBe(true); + expect(tableHeadings.includes('Overall Status')).toBe(true); + expect(tableHeadings.includes('R&D Version')).toBe(true); + expect(tableHeadings.includes('Draft Review')).toBe(true); + expect(tableHeadings.includes('Candidate Review')).toBe(true); + expect(tableHeadings.includes('Recommended Version')).toBe(true); + // More than just the header row if populated + expect(tableRowCount).toBeGreaterThan(1); + }); + }); + + it('renders page with filter options', async () => { + await getPage({ role: false, url: '/data-management' }, async page => { + await text(page, 'li ::-p-text(Filter)'); + const allOption = await text(page, 'li button ::-p-text(All Plans)'); + const rdOption = await text(page, 'li button ::-p-text(R&D Complete)'); + const draftOption = await text( + page, + 'li button ::-p-text(In Draft Review)' + ); + const candidateOption = await text( + page, + 'li button ::-p-text(In Candidate Review)' + ); + const recommendedOption = await text( + page, + 'li button ::-p-text(Recommended Plans)' + ); + + expect(allOption).toMatch(/All Plans \(\d+\)/); + expect(rdOption).toMatch(/R&D Complete \(\d+\)/); + expect(draftOption).toMatch(/In Draft Review \(\d+\)/); + expect(candidateOption).toMatch(/In Candidate Review \(\d+\)/); + expect(recommendedOption).toMatch(/Recommended Plans \(\d+\)/); + }); + }); +}); diff --git a/client/tests/e2e/Reports.e2e.test.js b/client/tests/e2e/Reports.e2e.test.js new file mode 100644 index 000000000..92bc8ab04 --- /dev/null +++ b/client/tests/e2e/Reports.e2e.test.js @@ -0,0 +1,244 @@ +import getPage from '../util/getPage'; +import { text } from './util'; + +describe('Reports page', () => { + it('renders reports page', async () => { + await getPage( + { role: false, url: '/reports' }, + async (page, { consoleErrors }) => { + await page.waitForSelector( + 'h1 ::-p-text(Assistive Technology Interoperability Reports)' + ); + + await page.waitForSelector('h2 ::-p-text(Introduction)'); + await page.waitForSelector('h2 ::-p-text(Support Levels)'); + + const tableRowsLength = await page.$eval( + 'table[aria-label="Support Levels"]', + el => Array.from(el.rows).length + ); + + // Check that the currently 'required' reports combinations exist; these + // combinations must exist in the table to be on this page + await page.waitForSelector('th ::-p-text(Test Plan)'); + await page.waitForSelector('th ::-p-text(JAWS and Chrome)'); + await page.waitForSelector('th ::-p-text(NVDA and Chrome)'); + await page.waitForSelector( + 'th ::-p-text(VoiceOver for macOS and Safari)' + ); + + // There is more than just the thead row + expect(tableRowsLength).toBeGreaterThan(1); + + expect(consoleErrors).toHaveLength(0); + } + ); + }); +}); + +describe('Report page for recommended report', () => { + const checkForHeading = async (page, selector, target) => { + return page.$$eval( + selector, + (els, target) => { + let regex; + switch (target) { + case 'jawsChrome': + regex = /^JAWS\s+(.*?)\s+and\s+Chrome$/; + break; + case 'nvdaChrome': + regex = /^NVDA\s+(.*?)\s+and\s+Chrome$/; + break; + case 'voiceoverSafari': + regex = /^VoiceOver for macOS\s+(.*?)\s+and\s+Safari$/; + break; + default: + break; + } + + let found = false; + for (let el of Array.from(els)) { + const headingText = el.innerText.trim(); + if (regex.test(headingText)) { + found = true; + break; + } + } + return found; + }, + target + ); + }; + + it('renders page', async () => { + await getPage({ role: false, url: '/report/67' }, async page => { + await page.waitForSelector( + 'h1 ::-p-text(Checkbox Example (Mixed-State))' + ); + await page.waitForSelector('h2 ::-p-text(Introduction)'); + await page.waitForSelector('h2 ::-p-text(Metadata)'); + await page.waitForSelector('details summary ::-p-text(Approved Report)'); + await page.waitForSelector( + 'a[role="button"] ::-p-text(View Complete Results)' + ); + + await page.waitForSelector('th ::-p-text(Test Name)'); + await page.waitForSelector('th ::-p-text(Must-Have Behaviors)'); + await page.waitForSelector('th ::-p-text(Should-Have Behaviors)'); + await page.waitForSelector('th ::-p-text(May-Have Behaviors)'); + + // Check that the reported date is valid (format is MMM D, YYYY) + const reportCompletedOnText = await text( + page, + '::-p-text(Report completed on)' + ); + let validReportCompletedOnDate = false; + const dateFormatRegex = + /^(January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{1,2},\s+\d{4}$/; + const dateText = reportCompletedOnText.split('Report completed on ')[1]; + if (dateFormatRegex.test(dateText)) { + // Confirm if date is valid + const date = new Date(dateText); + validReportCompletedOnDate = !isNaN(date.getTime()); + } + + // Check that ' + headings are valid + const validJawsHeadingMatchFound = await checkForHeading( + page, + 'h2 ::-p-text(JAWS)', + 'jawsChrome' + ); + const validNvdaHeadingMatchFound = await checkForHeading( + page, + 'h2 ::-p-text(NVDA)', + 'nvdaChrome' + ); + const validVoiceoverHeadingMatchFound = await checkForHeading( + page, + 'h2 ::-p-text(VoiceOver for macOS)', + 'voiceoverSafari' + ); + + expect(validReportCompletedOnDate).toBe(true); + expect(validJawsHeadingMatchFound).toBe(true); + expect(validNvdaHeadingMatchFound).toBe(true); + expect(validVoiceoverHeadingMatchFound).toBe(true); + }); + }); + + it('clicks View Results button and navigates to /targets/:id page', async () => { + await getPage({ role: false, url: '/report/67' }, async page => { + const viewResultsButton = + 'a[role="button"] ::-p-text(View Complete Results)'; + + await page.waitForSelector(viewResultsButton); + await page.click(viewResultsButton); + + await page.waitForSelector( + 'h1 ::-p-text(Checkbox Example (Mixed-State))' + ); + await page.waitForSelector('h2 ::-p-text(Versions Summary)'); + await page.waitForSelector('h2 ::-p-text(Results for)'); + await page.waitForSelector('details summary ::-p-text(Approved Report)'); + const currentUrl = await page.url(); + + expect(currentUrl).toMatch(/^.*\/report\/\d+\/targets\/\d+/); + }); + }); +}); + +describe('Report page for candidate report', () => { + const checkForHeading = async (page, selector, headingText) => { + return page.$$eval( + selector, + (els, headingText) => + Array.from(els) + .map(el => el.innerText.trim()) + .includes(headingText), + headingText + ); + }; + + it('renders page', async () => { + await getPage({ role: false, url: '/report/24' }, async page => { + await page.waitForSelector('h1 ::-p-text(Modal Dialog Example)'); + await page.waitForSelector('h2 ::-p-text(Introduction)'); + await page.waitForSelector('h2 ::-p-text(Metadata)'); + await page.waitForSelector( + 'details summary ::-p-text(Unapproved Report)' + ); + await page.waitForSelector( + 'a[role="button"] ::-p-text(View Complete Results)' + ); + + await page.waitForSelector('th ::-p-text(Test Name)'); + await page.waitForSelector('th ::-p-text(Must-Have Behaviors)'); + await page.waitForSelector('th ::-p-text(Should-Have Behaviors)'); + await page.waitForSelector('th ::-p-text(May-Have Behaviors)'); + + // Check that the reported date is valid (format is MMM D, YYYY) + const reportCompletedOnText = await text( + page, + '::-p-text(Report completed on)' + ); + let validReportCompletedOnDate = false; + const dateFormatRegex = + /^(January|February|March|April|May|June|July|August|September|October|November|December)\s+\d{1,2},\s+\d{4}$/; + const dateText = reportCompletedOnText.split('Report completed on ')[1]; + if (dateFormatRegex.test(dateText)) { + // Confirm if date is valid + const date = new Date(dateText); + validReportCompletedOnDate = !isNaN(date.getTime()); + } + + // Check that ' + headings are valid + const validJawsHeadingMatchFound = await checkForHeading( + page, + 'h2 ::-p-text(JAWS)', + 'JAWS and Chrome' + ); + const validNvdaHeadingMatchFound = await checkForHeading( + page, + 'h2 ::-p-text(NVDA)', + 'NVDA and Chrome' + ); + const validVoiceoverHeadingMatchFound = await checkForHeading( + page, + 'h2 ::-p-text(VoiceOver for macOS)', + 'VoiceOver for macOS and Safari' + ); + + expect(validReportCompletedOnDate).toBe(true); + expect(validJawsHeadingMatchFound).toBe(true); + expect(validNvdaHeadingMatchFound).toBe(true); + expect(validVoiceoverHeadingMatchFound).toBe(true); + }); + }); + + it('clicks View Results button and navigates to /targets/:id page', async () => { + await getPage({ role: false, url: '/report/24' }, async page => { + const viewResultsButton = + 'a[role="button"] ::-p-text(View Complete Results)'; + + await page.waitForSelector(viewResultsButton); + await page.click(viewResultsButton); + + await page.waitForSelector('h1 ::-p-text(Modal Dialog Example)'); + + const isVersionsSummaryFound = await page.evaluate(() => { + const elementsWithText = Array.from( + document.querySelectorAll('h2') + ).filter(element => element.textContent.includes('Versions Summary')); + return elementsWithText.length > 0; + }); + await page.waitForSelector('h2 ::-p-text(Results for)'); + await page.waitForSelector( + 'details summary ::-p-text(Unapproved Report)' + ); + const currentUrl = await page.url(); + + expect(isVersionsSummaryFound).toBe(false); + expect(currentUrl).toMatch(/^.*\/report\/\d+\/targets\/\d+/); + }); + }); +}); diff --git a/client/tests/e2e/TestPlanVersions.e2e.test.js b/client/tests/e2e/TestPlanVersions.e2e.test.js new file mode 100644 index 000000000..958e1d27e --- /dev/null +++ b/client/tests/e2e/TestPlanVersions.e2e.test.js @@ -0,0 +1,54 @@ +import getPage from '../util/getPage'; +import { text } from './util'; + +describe('Versions page for pattern with highest report being recommended', () => { + it('renders page h1', async () => { + await getPage( + { role: false, url: '/data-management/checkbox-tri-state' }, + async (page, { consoleErrors }) => { + await text( + page, + 'h1 ::-p-text(Checkbox Example (Tri State) Test Plan Versions)' + ); + + expect(consoleErrors).toHaveLength(0); + } + ); + }); +}); + +describe('Versions page for pattern with highest report being candidate', () => { + it('renders page h1', async () => { + await getPage( + { role: false, url: '/data-management/modal-dialog' }, + async page => { + await text( + page, + 'h1 ::-p-text(Modal Dialog Example Test Plan Versions)' + ); + } + ); + }); +}); + +describe('Versions page for pattern with highest report being draft', () => { + it('renders page h1', async () => { + await getPage( + { role: false, url: '/data-management/alert' }, + async page => { + await text(page, 'h1 ::-p-text(Alert Example Test Plan Versions)'); + } + ); + }); +}); + +describe('Versions page for pattern with highest report being R&D', () => { + it('renders page h1', async () => { + await getPage( + { role: false, url: '/data-management/banner' }, + async page => { + await text(page, 'h1 ::-p-text(Banner Landmark Test Plan Versions)'); + } + ); + }); +}); diff --git a/client/tests/e2e/TestQueue.e2e.test.js b/client/tests/e2e/TestQueue.e2e.test.js index f0dc1b409..f8168bed3 100644 --- a/client/tests/e2e/TestQueue.e2e.test.js +++ b/client/tests/e2e/TestQueue.e2e.test.js @@ -1,17 +1,5 @@ import getPage from '../util/getPage'; - -const text = async (page, selector, { wait = true } = {}) => { - if (wait) await page.waitForSelector(selector); - return page.$eval(selector, el => el.innerText); -}; - -const display = async (page, selector, { wait = true } = {}) => { - if (wait) await page.waitForSelector(selector); - return page.$eval(selector, el => { - const styles = window.getComputedStyle(el); - return styles.getPropertyValue('display'); - }); -}; +import { text, display } from './util'; describe('Test Queue common traits', () => { it('renders page h1', async () => { @@ -31,14 +19,19 @@ describe('Test Queue admin traits when reports exist', () => { }); it('renders page with instructions', async () => { - await getPage({ role: 'admin', url: '/test-queue' }, async page => { - const instructionsSelector = '[data-testid="test-queue-instructions"]'; - const instructionsText = await text(page, instructionsSelector); + await getPage( + { role: 'admin', url: '/test-queue' }, + async (page, { consoleErrors }) => { + const instructionsSelector = '[data-testid="test-queue-instructions"]'; + const instructionsText = await text(page, instructionsSelector); + + expect(instructionsText).toBe( + 'Manage the test plans, assign yourself a test plan or start executing one that is already assigned to you.' + ); - expect(instructionsText).toBe( - 'Manage the test plans, assign yourself a test plan or start executing one that is already assigned to you.' - ); - }); + expect(consoleErrors).toHaveLength(0); + } + ); }); it('renders page with known pattern sections', async () => { diff --git a/client/tests/e2e/TestReview.e2e.test.js b/client/tests/e2e/TestReview.e2e.test.js new file mode 100644 index 000000000..0f7bab857 --- /dev/null +++ b/client/tests/e2e/TestReview.e2e.test.js @@ -0,0 +1,104 @@ +import getPage from '../util/getPage'; +import { text } from './util'; + +describe('Test Review page', () => { + const getReviewPageElements = async (page, { isV2 = false } = {}) => { + await text(page, 'h2 ::-p-text(About This Test Plan)'); + await text(page, 'h2 ::-p-text(Supporting Documentation)'); + await text(page, 'h2 ::-p-text(Tests)'); + await text(page, '::-p-text(Filter tests by covered AT)'); + await text(page, 'button ::-p-text(All ATs)'); + await text(page, 'button ::-p-text(JAWS)'); + await text(page, 'button ::-p-text(NVDA)'); + await text(page, 'button ::-p-text(VoiceOver for macOS)'); + await text(page, 'h3 ::-p-text(Test 1:)'); + await text(page, 'h4 ::-p-text(JAWS)'); + await text(page, 'h4 ::-p-text(NVDA)'); + await text(page, 'h4 ::-p-text(VoiceOver for macOS)'); + await text(page, 'h5 ::-p-text(Instructions)'); + await text(page, 'h5 ::-p-text(Assertions)'); + await text(page, 'th ::-p-text(Priority)'); + await text(page, 'th ::-p-text(Assertion Statement)'); + if (isV2) { + await text(page, '::-p-text(To perform a task with)'); + await text(page, 'th ::-p-text(Assertion Phrase)'); + } + + // Confirm open test page works + const openTestPageButtonSelector = 'button ::-p-text(Open Test Page)'; + await page.click(openTestPageButtonSelector); + + // Allow additional time for popup to open + await page.waitForNetworkIdle(); + + const pages = await global.browser.pages(); + const popupPage = pages[pages.length - 1]; + + // Check for 'Run Test Setup' button + await popupPage.waitForSelector('button ::-p-text(Run Test Setup)'); + }; + + it('renders page for review page before test format v2', async () => { + await getPage( + { role: false, url: '/test-review/1' }, + async (page, { consoleErrors }) => { + await text( + page, + 'h1 ::-p-text(Alert Example Test Plan V22.04.14 (Deprecated))' + ); + + await getReviewPageElements(page); + expect(consoleErrors).toHaveLength(0); + } + ); + }); + + it('renders page for review page after test format v2', async () => { + await getPage({ role: false, url: '/test-review/65' }, async page => { + await text( + page, + 'h1 ::-p-text(Alert Example Test Plan V23.12.06 (Deprecated))' + ); + await getReviewPageElements(page, { isV2: true }); + }); + }); + + it('opens latest review page for pattern from /data-management', async () => { + await getPage( + { + role: false, + url: '/data-management' + }, + async page => { + await text(page, 'h1 ::-p-text(Data Management)'); + + const latestAlertVersionLink = await page.evaluateHandle(() => { + let rows = Array.from(document.querySelectorAll('tr')); + for (let row of rows) { + const thText = row.querySelector('th').textContent.trim(); + if (thText === 'Alert Example') { + // Get the name of the latest Alert Example version from the 3rd + // td, R&D Column, but also the 2nd possible link in the row + return row.querySelectorAll('a')[1]; + } + } + return null; + }); + + // Capture version text name and navigate to review page + const latestAlertVersionLinkText = + await latestAlertVersionLink.evaluate(el => el.textContent.trim()); + await latestAlertVersionLink.click(); + await page.waitForNavigation({ + waitUntil: ['domcontentloaded', 'networkidle0'] + }); + + await text( + page, + `h1 ::-p-text(Alert Example Test Plan ${latestAlertVersionLinkText})` + ); + await getReviewPageElements(page, { isV2: true }); + } + ); + }); +}); diff --git a/client/tests/e2e/TestRun.e2e.test.js b/client/tests/e2e/TestRun.e2e.test.js new file mode 100644 index 000000000..07fd8f676 --- /dev/null +++ b/client/tests/e2e/TestRun.e2e.test.js @@ -0,0 +1,375 @@ +import getPage from '../util/getPage'; +import { text } from './util'; + +describe('Test Run when not signed in', () => { + it('renders invalid request when attempting to go directly to /run/:id', async () => { + await getPage({ role: false, url: '/run/19' }, async page => { + const h1Text = await text(page, 'h1'); + const currentUrl = await page.url(); + + expect(h1Text).toBe('Whoops! Unable to complete request'); + expect(currentUrl.includes('/invalid-request')).toBe(true); + }); + }); + + it('renders /test-plan-report/:id and can navigate between tests', async () => { + // This should be NVDA + Chrome + Modal Dialog Example with 12 tests + await getPage( + { role: false, url: '/test-plan-report/19' }, + async (page, { consoleErrors }) => { + const h1Text = await text(page, 'h1'); + expect(h1Text.includes('Test 1:')).toBe(true); + + await page.waitForSelector('nav#test-navigator-nav ol'); + const testNavigatorListItemsHandle = await page.evaluateHandle(() => { + const testNavigatorListSelector = 'nav#test-navigator-nav ol'; + const testNavigatorList = document.querySelector( + testNavigatorListSelector + ); + return Array.from(testNavigatorList.querySelectorAll('li')); + }); + + const testNavigatorListItemsMap = + await testNavigatorListItemsHandle.getProperties(); + const testNavigatorListItems = Array.from( + testNavigatorListItemsMap.values() + ); + const listItemsLength = testNavigatorListItems.length; + + // Click each navigation item and confirm the h1 on page has changed + for (const [index, li] of testNavigatorListItems.entries()) { + // Randomly navigate using the navigation link or the next button + if (Math.random()) + await li.evaluate(el => el.querySelector('a').click()); + else await page.click('button ::-p-text(Next Test)'); + + await page.waitForSelector(`h1 ::-p-text(Test ${index + 1}:)`); + await page.waitForSelector( + `div[class="info-label"] ::-p-text(Test Plan:)` + ); + await page.waitForSelector(`div[class="info-label"] ::-p-text(AT:)`); + await page.waitForSelector( + `div[class="info-label"] ::-p-text(Browser:)` + ); + await page.waitForSelector( + `div[class="info-label"] ::-p-text(${listItemsLength} tests to view)` + ); + await page.waitForSelector(`h2 ::-p-text(Instructions)`); + await page.waitForSelector(`h2 ::-p-text(Record Results)`); + await page.waitForSelector(`h3 ::-p-text(After)`); + + const updatedUrl = await page.url(); + expect(updatedUrl).toMatch( + new RegExp(`/test-plan-report/19#${index + 1}$`) + ); + } + expect(consoleErrors).toHaveLength(0); + } + ); + }); +}); + +describe('Test Run when signed in as tester', () => { + const assignSelfAndNavigateToRun = async page => { + const modalDialogSectionButtonSelector = + 'button#disclosure-btn-modal-dialog-0'; + const modalDialogTableSelector = + 'table[aria-label="Reports for Modal Dialog Example V24.06.07 in draft phase"]'; + const startTestingButtonSelector = + 'a[role="button"] ::-p-text(Start Testing)'; + + // Expand Modal Dialog's V24.06.07 section + await page.waitForSelector(modalDialogSectionButtonSelector); + await page.click(modalDialogSectionButtonSelector); + + // Wait for the table to render + await page.waitForSelector(modalDialogTableSelector); + + await page.$eval(modalDialogTableSelector, el => { + // First button found on table would be 'Assign Yourself' + el.querySelector('button').click(); + }); + + await page.waitForNetworkIdle(); + await page.waitForSelector('::-p-text(Unassign Yourself)'); + await page.waitForSelector(startTestingButtonSelector); + await page.click(startTestingButtonSelector); + + // Wait for navigation to Test Run page to complete + await page.waitForNavigation({ + waitUntil: ['domcontentloaded', 'networkidle0'] + }); + + const atBrowserModalHeadingSelector = + 'h1 ::-p-text(Assistive Technology and Browser Details)'; + const atBrowserModalAtVersionSelectSelector = + 'select[data-testid="at-browser-modal-select"]'; + const atBrowserModalBrowserVersionInputSelector = + 'input[data-testid="at-browser-modal-input"][class="form-control"]'; + const atBrowserModalSaveButtonSelector = + 'button ::-p-text(Save and Continue)'; + + await page.waitForSelector(atBrowserModalHeadingSelector); + await page.select(atBrowserModalAtVersionSelectSelector, '2'); + await page.$eval( + atBrowserModalBrowserVersionInputSelector, + input => (input.value = '') + ); + await page.type( + atBrowserModalBrowserVersionInputSelector, + '1.TestBrowserVersion' + ); + await page.click(atBrowserModalSaveButtonSelector); + await page.waitForNetworkIdle(); + }; + + it('self assigns tester on Test Queue page and opens test run', async () => { + await getPage({ role: 'tester', url: '/test-queue' }, async page => { + await assignSelfAndNavigateToRun(page); + + const h1Text = await text(page, 'h1 ::-p-text(Test 1)'); + const currentUrl = await page.url(); + + expect(h1Text.includes('Test 1:')).toBe(true); + expect(currentUrl).toMatch(/^.*\/run\/\d+/); + }); + }); + + it('navigates between tests', async () => { + await getPage({ role: 'tester', url: '/test-queue' }, async page => { + await assignSelfAndNavigateToRun(page); + + await page.waitForSelector('h1 ::-p-text(Test 1)'); + const testNavigatorListSelector = 'nav#test-navigator-nav ol'; + await page.waitForSelector(testNavigatorListSelector); + + const listItemsLength = await page.$eval( + testNavigatorListSelector, + el => { + return el.children.length; + } + ); + + // Click each navigation item and confirm the h1 on page has changed + for (let sequence = 1; sequence <= listItemsLength; sequence++) { + // const sequence = i + 1; + const liSelector = `nav#test-navigator-nav ol li:nth-child(${sequence})`; + + // Select the next test to navigate to + await page.$eval(liSelector, el => el.querySelector('a').click()); + await page.waitForNetworkIdle(); + + await page.waitForSelector(`h1 ::-p-text(Test ${sequence}:)`); + await page.waitForSelector( + `div[class="info-label"] ::-p-text(Test Plan:)` + ); + await page.waitForSelector(`div[class="info-label"] ::-p-text(AT:)`); + await page.waitForSelector( + `div[class="info-label"] ::-p-text(Browser:)` + ); + await page.waitForSelector( + `div[class="info-label"] ::-p-text(0 of ${listItemsLength} tests completed)` + ); + await page.waitForSelector(`h2 ::-p-text(Instructions)`); + await page.waitForSelector(`h2 ::-p-text(Record Results)`); + await page.waitForSelector(`h3 ::-p-text(After)`); + } + + expect(listItemsLength).toBeGreaterThan(1); + }); + }); + + it('clamps the test index to the bounds of the test list', async () => { + await getPage({ role: 'tester', url: '/test-queue' }, async page => { + await assignSelfAndNavigateToRun(page); + + await page.waitForSelector('h1 ::-p-text(Test 1)'); + const url = await page.url(); + await page.goto(`${url}#0`); + await page.waitForNetworkIdle(); + let h1Text = await text(page, 'h1'); + expect(h1Text).toMatch(/^Test 1:/); + + const numberOfTests = await page.$eval( + 'nav#test-navigator-nav ol', + el => { + return el.children.length; + } + ); + await page.goto(`${url}#${numberOfTests + 10}`); + await page.waitForNetworkIdle(); + h1Text = await text(page, 'h1'); + expect(h1Text).toMatch(new RegExp(`Test ${numberOfTests}:`)); + }); + }); + + it('inputs results and navigates between tests to confirm saving', async () => { + async function getGeneratedCheckedAssertionCount(page) { + return await page.evaluate(() => { + const radioGroups = document.querySelectorAll( + 'input[type="radio"][id^="pass-"]' + ); + let yesCount = 0; + + for (let i = 0; i < radioGroups.length; i += 2) { + if (i % 4 === 0) { + radioGroups[i].click(); // Click 'Yes' radio + yesCount++; + } else { + radioGroups[i + 1].click(); // Click 'No' radio + } + } + + return yesCount; + }); + } + + await getPage({ role: 'tester', url: '/test-queue' }, async page => { + await assignSelfAndNavigateToRun(page); + + await page.waitForSelector('h1 ::-p-text(Test 1)'); + await page.waitForSelector('button ::-p-text(Next Test)'); + + const radioSelector = 'input[type="radio"]'; + const test1NavSelector = 'nav#test-navigator-nav ol li:nth-child(1)'; + const test2NavSelector = 'nav#test-navigator-nav ol li:nth-child(2)'; + const nextTestButtonSelector = 'button ::-p-text(Next Test)'; + const previousTestButtonSelector = 'button ::-p-text(Previous Test)'; + + // Randomly select radio buttons on first test + const generatedCheckedTest1Count = + await getGeneratedCheckedAssertionCount(page, radioSelector); + + // Navigate to test 2 with navigation menu + await page.$eval(test2NavSelector, el => el.querySelector('a').click()); + await page.waitForNetworkIdle(); + await page.waitForSelector('h1 ::-p-text(Test 2:)'); + await page.waitForSelector('button ::-p-text(Next Test)'); + const generatedCheckedTest2Count = + await getGeneratedCheckedAssertionCount(page, radioSelector); + + // Navigate to test 3 with next button + await page.click(nextTestButtonSelector); + await page.waitForNetworkIdle(); + await page.waitForSelector('h1 ::-p-text(Test 3:)'); + await page.waitForSelector('button ::-p-text(Next Test)'); + const test3CheckedCount = await page.$$eval( + radioSelector, + els => els.filter(radio => radio.checked).length + ); + + // Navigate back to test 2 with previous button + await page.click(previousTestButtonSelector); + await page.waitForNetworkIdle(); + await page.waitForSelector('h1 ::-p-text(Test 2:)'); + await page.waitForSelector('button ::-p-text(Next Test)'); + const test2CheckedCount = await page.$$eval( + radioSelector, + els => els.filter(radio => radio.checked).length + ); + + // Navigate back to Test 1 with navigation menu + await page.$eval(test1NavSelector, el => el.querySelector('a').click()); + await page.waitForNetworkIdle(); + await page.waitForSelector('h1 ::-p-text(Test 1:)'); + await page.waitForSelector('button ::-p-text(Next Test)'); + const test1CheckedCount = await page.$$eval( + radioSelector, + els => + els.filter(radio => radio.checked && radio.id.includes('-yes')).length + ); + + expect(test1CheckedCount).toBe(generatedCheckedTest1Count); + expect(test2CheckedCount).toBe(generatedCheckedTest2Count * 2); // Both 'Yes' and 'No' are checked + expect(test3CheckedCount).toBe(0); + }); + }); + + it('inputs results and successfully submits', async () => { + await getPage({ role: 'tester', url: '/test-queue' }, async page => { + await assignSelfAndNavigateToRun(page); + + await page.waitForSelector('h1 ::-p-text(Test 1)'); + + // Confirm that submission cannot happen with empty form + // Specificity with selector because there's a 2nd 'hidden' button coming + // from the harness which is what is actually called for the submit event + const submitResultsButtonSelector = + 'button[class="btn btn-primary"] ::-p-text(Submit Results)'; + await page.waitForSelector(submitResultsButtonSelector); + await page.click(submitResultsButtonSelector); + await page.waitForNetworkIdle(); + await page.waitForSelector('::-p-text((required))'); + + // Should refocus on topmost output textarea on page + const activeElementAfterEmptySubmit = await page.evaluate(() => { + return { + id: document.activeElement.id, + nodeName: document.activeElement.nodeName.toLowerCase() + }; + }); + + // Input output for valid submission + await page.evaluate(() => { + const yesRadios = document.querySelectorAll( + 'input[data-testid^="radio-yes-"]' + ); + const noRadios = document.querySelectorAll( + 'input[data-testid^="radio-no-"]' + ); + const noUndesiredRadios = document.querySelectorAll( + 'input[id^="problem-"][id$="-true"]' + ); + const noOutputCheckboxes = document.querySelectorAll( + 'input[id^="no-output-checkbox"]' + ); + + yesRadios.forEach((radio, index) => { + if (index % 2 === 0) { + radio.click(); + } else { + noRadios[index].click(); + } + }); + + noUndesiredRadios.forEach(radio => { + radio.click(); + }); + + noOutputCheckboxes.forEach(checkbox => { + checkbox.click(); + }); + }); + // Submit valid form + await page.click(submitResultsButtonSelector); + await page.waitForNetworkIdle(); + await page.waitForSelector( + '::-p-text(This test has conflicting results)' + ); + await page.waitForSelector('h2 ::-p-text(Test Results)'); + await page.waitForSelector('button ::-p-text(Edit Results)'); + + expect(activeElementAfterEmptySubmit.id).toBe('speechoutput-0'); + expect(activeElementAfterEmptySubmit.nodeName).toBe('textarea'); + }); + }); + + it('opens popup with content after clicking "Open Test Page" button', async () => { + await getPage({ role: 'tester', url: '/test-queue' }, async page => { + await assignSelfAndNavigateToRun(page); + + // Confirm open test page works + const openTestPageButtonSelector = 'button ::-p-text(Open Test Page)'; + await page.click(openTestPageButtonSelector); + + // Allow additional time for popup to open + await page.waitForNetworkIdle(); + + const pages = await global.browser.pages(); + const popupPage = pages[pages.length - 1]; + + // Check for 'Run Test Setup' button + await popupPage.waitForSelector('button ::-p-text(Run Test Setup)'); + }); + }); +}); diff --git a/client/tests/e2e/UserSettings.e2e.test.js b/client/tests/e2e/UserSettings.e2e.test.js new file mode 100644 index 000000000..f796b7f4a --- /dev/null +++ b/client/tests/e2e/UserSettings.e2e.test.js @@ -0,0 +1,90 @@ +import getPage from '../util/getPage'; +import { text } from './util'; + +describe('User Settings when not signed in', () => { + it('does not render page if signed out', async () => { + await getPage({ role: false, url: '/account/settings' }, async page => { + const h1Text = await text(page, 'h1'); + const currentUrl = await page.url(); + + expect(h1Text).toBe('Whoops! Unable to complete request'); + expect(currentUrl.includes('/invalid-request')).toBe(true); + }); + }); +}); + +describe('User Settings when signed in as vendor', () => { + it('does not render page if signed in as vendor', async () => { + await getPage({ role: 'vendor', url: '/account/settings' }, async page => { + const h1Text = await text(page, 'h1'); + const currentUrl = await page.url(); + + expect(h1Text).toBe('Whoops! Page not found'); + expect(currentUrl.includes('/404')).toBe(true); + }); + }); +}); + +describe('User Settings common traits', () => { + it('renders page h1', async () => { + await getPage({ role: 'tester', url: '/account/settings' }, async page => { + const h1Text = await text(page, 'h1'); + expect(h1Text).toBe('Settings'); + }); + }); + + it("renders tester's user details and assistive technology sections", async () => { + await getPage({ role: 'tester', url: '/account/settings' }, async page => { + await page.waitForSelector('h2 ::-p-text(User Details)'); + await page.waitForSelector('h2 ::-p-text(Assistive Technology Settings)'); + + const tester = 'joe-the-tester'; + await page.waitForSelector(`p a[href="https://github.com/${tester}"]`); + }); + }); + + it('renders testable assistive technologies status and update on save', async () => { + await getPage( + { role: 'tester', url: '/account/settings' }, + async (page, { consoleErrors }) => { + const testableAtsStatusTextBeforeSave = await text( + page, + 'p[data-testid="testable-ats-status"]' + ); + expect(testableAtsStatusTextBeforeSave).toBe( + 'You have not yet selected any assistive technologies.' + ); + + const jawsOptionSelector = 'input[id="1"][type="checkbox"]'; + const nvdaOptionSelector = 'input[id="2"][type="checkbox"]'; + const saveButtonSelector = 'button[type="submit"]'; + const saveButtonText = await text(page, saveButtonSelector); + + await page.click(jawsOptionSelector); + await page.click(nvdaOptionSelector); + await page.click(saveButtonSelector); + + await page.waitForNetworkIdle(); + + const testableAtsStatusTextAfterSave = await text( + page, + 'p[data-testid="testable-ats-status"]' + ); + const selectedAtsListItems = await page.$eval('ul', el => { + const liElements = el.querySelectorAll('li'); + return Array.from(liElements, li => li.innerText.trim()); + }); + + expect(saveButtonText).toBe('Save'); + expect(testableAtsStatusTextAfterSave).toBe( + 'You can currently test the following assistive technologies:' + ); + expect(selectedAtsListItems.length).toBe(2); + expect(selectedAtsListItems.includes('JAWS')).toBe(true); + expect(selectedAtsListItems.includes('NVDA')).toBe(true); + + expect(consoleErrors).toHaveLength(0); + } + ); + }); +}); diff --git a/client/tests/e2e/smokeTest.e2e.test.js b/client/tests/e2e/smokeTest.e2e.test.js index b49f8bbd5..cb438707d 100644 --- a/client/tests/e2e/smokeTest.e2e.test.js +++ b/client/tests/e2e/smokeTest.e2e.test.js @@ -1,16 +1,22 @@ import getPage from '../util/getPage'; +import { text } from './util'; describe('smoke test', () => { it('end-to-end tests can simultaneously sign in with all roles', async () => { await Promise.all([ getPage({ role: 'admin', url: '/test-queue' }, async page => { + // Wait for page load + await page.waitForSelector('div[data-testid="page-status"]'); + // Only admins can remove rows from the test queue await page.waitForSelector( 'td [type="button"] ::-p-text(Delete Report)' ); }), - getPage({ role: 'tester', url: '/test-queue' }, async page => { + // Wait for page load + await page.waitForSelector('div[data-testid="page-status"]'); + // Testers can assign themselves await page.waitForSelector('table ::-p-text(Assign Yourself)'); const adminOnlyRemoveButton = await page.$( @@ -18,10 +24,12 @@ describe('smoke test', () => { ); expect(adminOnlyRemoveButton).toBe(null); }), - getPage( { role: 'vendor', url: '/test-queue' }, async (page, { baseUrl }) => { + // Wait for page load + await page.waitForSelector('div[data-testid="page-status"]'); + // Vendors get the same test queue as signed-out users await page.waitForSelector('button ::-p-text(V22.04.14)'); await page.click('button ::-p-text(V22.04.14)'); @@ -38,7 +46,6 @@ describe('smoke test', () => { await page.waitForSelector('table'); } ), - getPage({ role: false, url: '/test-queue' }, async page => { // Signed-out users can only view tests, not run them await page.waitForSelector('td [role="button"] ::-p-text(View Tests)'); @@ -50,8 +57,7 @@ describe('smoke test', () => { await Promise.all([ getPage({ role: false, url: '/' }, async page => { await page.waitForSelector('h1'); - const h1Handle = await page.waitForSelector('h1'); - const h1Text = await h1Handle.evaluate(h1 => h1.innerText); + const h1Text = await text(page, 'h1'); expect(h1Text).toBe( 'Enabling Interoperability for Assistive Technology Users' ); @@ -60,24 +66,21 @@ describe('smoke test', () => { // Wait for an h2 because an h1 will show while the page is // still loading await page.waitForSelector('h2'); - const h1Handle = await page.waitForSelector('h1'); - const h1Text = await h1Handle.evaluate(h1 => h1.innerText); + const h1Text = await text(page, 'h1'); expect(h1Text).toBe('Assistive Technology Interoperability Reports'); }), getPage({ role: false, url: '/data-management' }, async page => { // Wait for an h2 because an h1 will show while the page is // still loading await page.waitForSelector('h2'); - const h1Handle = await page.waitForSelector('h1'); - const h1Text = await h1Handle.evaluate(h1 => h1.innerText); + const h1Text = await text(page, 'h1'); expect(h1Text).toBe('Data Management'); }), getPage({ role: false, url: '/test-plan-report/15' }, async page => { // Wait for an h2 because an h1 will show while the page is // still loading await page.waitForSelector('h2'); - const h1Handle = await page.waitForSelector('h1'); - const h1Text = await h1Handle.evaluate(h1 => h1.innerText); + const h1Text = await text(page, 'h1'); expect(h1Text).toBe( 'Test 1:\nNavigate forwards to a not pressed toggle button' ); @@ -86,8 +89,7 @@ describe('smoke test', () => { // Wait for an h2 because an h1 will show while the page is // still loading await page.waitForSelector('h2'); - const h1Handle = await page.waitForSelector('h1'); - const h1Text = await h1Handle.evaluate(h1 => h1.innerText); + const h1Text = await text(page, 'h1'); expect(h1Text).toBe( 'Test 1:\nNavigate forwards to a not pressed toggle button' ); diff --git a/client/tests/e2e/snapshots/saved/_.html b/client/tests/e2e/snapshots/saved/_.html new file mode 100644 index 000000000..1b0fdcadb --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_.html @@ -0,0 +1,270 @@ + + + + + + + + + Home | ARIA-AT + + +
      +
      + +
      +
      +
      +
      +

      Enabling Interoperability for Assistive Technology Users

      +
      +
      +

      + Note: The + ARIA-AT Project + is managed by the + ARIA-AT Community Group + in coordination with the + Authoring Practices Task Force + of the + ARIA Working Group. The W3C staff contact is + Daniel Montalvo. +

      +

      + Today, different screen readers often yield conflicting + experiences when presenting a web page, disadvantaging or even + excluding some users. These differences also create + accessibility design and test barriers for web developers. +

      +

      + On the other hand, browsers are interoperable for people who + do not use assistive technologies. That is, different browsers + provide equivalent experiences. Browser interoperability + facilitates an inclusive web. +

      +

      + Assistive technology users deserve equal inclusion. The + ARIA-AT project aims to empower equal inclusion by realizing + interoperability for AT users. +

      +

      + Read more about how the AT interoperability gap hinders + inclusion on the web for people with disabilities. +

      +
      +
      + +
      +
      +
      +
      +
      +

      How are we improving interoperability?

      +
        +
      • + +

        Proposing expectations for ATs

        +

        + We have written initial drafts for more than a thousand + tests that articulate expected screen reader behaviors for + 40 examples of common web design patterns. View the + Test Writing Progress Report + and + view the draft test plans + preview. +

        +
      • +
      • + +

        Testing proposed expectations

        +

        + This website enables us to manage test data, run tests with + multiple testers, review results, and publish reports. View + our progress on the + test queue page. +

        +
      • +
      • + +

        Building industry consensus

        +

        + Once a pattern has a reviewed test plan with results data, a + candidate report is published and the process of building + consensus around the plan begins. View reports generated + from candidate test plans on the + reports page. +

        +
      • +
      • + +

        Enabling scalable automated testing

        +

        + In order to regularly collect test results at scale for + multiple web design patterns, browsers, and ATs, we are + developing an industry standard for automating assistive + technology. Read the + explainer for a draft AT automation standard + and + explore the code repository + where experimental drivers are being developed. +

        +
      • +
      +
      +
      +
      +
      +

      Get Involved

      +

      + Enabling AT interoperability is a large, ongoing endeavor that + requires industry-wide collaboration and support. The W3C + ARIA-AT Community Group is currently focusing on a stable and + mature test suite for five screen readers. In the future, we + plan to test additional screen readers and other kinds of + assistive technologies with a broader set of web design patterns + and test material. +

      +

      Learn how you can help by:

      +
        +
      1. + Reading more about the project and spreading awareness of + its mission +
      2. +
      3. + Browsing the ARIA-AT Frequently Asked Questions (FAQ) +
      4. +
      5. + Joining the community group + to participate in our mailing list and conference calls +
      6. +
      +
      +
      +
      +
      + +
      + + + diff --git a/client/tests/e2e/snapshots/saved/_404.html b/client/tests/e2e/snapshots/saved/_404.html new file mode 100644 index 000000000..3e7edfdea --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_404.html @@ -0,0 +1,88 @@ + + + + + + + + + Page Not Found | ARIA-AT + + +
      +
      + +
      +
      +
      +
      +

      Whoops! Page not found

      +
      +
      +
      + +
      + + + diff --git a/client/tests/e2e/snapshots/saved/_account_settings.html b/client/tests/e2e/snapshots/saved/_account_settings.html new file mode 100644 index 000000000..460460d0f --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_account_settings.html @@ -0,0 +1,148 @@ + + + + + + + + + Settings | ARIA-AT + + +
      +
      + +
      +
      +
      +
      +

      Settings

      +
      +

      User Details

      +

      + joe-the-admin +

      +

      Assistive Technology Settings

      +
      +

      + You have not yet selected any assistive technologies. +

      +
      +

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

      + +

      Assistive Technologies

      +
      +
      + +
      +
      + +
      +
      + +
      +
      + + +
      +
      +
      +
      + +
      + + + diff --git a/client/tests/e2e/snapshots/saved/_candidate-review.html b/client/tests/e2e/snapshots/saved/_candidate-review.html new file mode 100644 index 000000000..4fb2ede26 --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_candidate-review.html @@ -0,0 +1,333 @@ + + + + + + + + + Candidate Review | ARIA-AT + + +
      +
      + +
      +
      +
      +

      Candidate Review

      +

      Introduction

      +

      + This page summarizes the test results for each AT and Browser which + executed the Test Plan. +

      +
      +

      + +

      +
      +
      + + + + + + + + + + + + + + + + + + + +
      Candidate Test PlansLast UpdatedTarget Completion DateReview StatusResults Summary
      + Modal Dialog Example V22.05.26 (18 Tests) + Jul 6, 2022Jan 2, 2023 +
      +
      + 97% +
      +
      97%
      +
      3 assertions failed across + 2 tests run with 1 browser +
      +
      +
      +
      +
      +

      + +

      +
      +
      + + + + + + + + + + + + + + + + + + + +
      Candidate Test PlansLast UpdatedTarget Completion DateReview StatusResults Summary
      + Modal Dialog Example V22.05.26 (18 Tests) + Jul 6, 2022Jan 2, 2023 +
      +
      + 97% +
      +
      97%
      +
      3 assertions failed across + 2 tests run with 1 browser +
      +
      +
      +
      +
      +

      + +

      +
      +
      + + + + + + + + + + + + + + + + + + + +
      Candidate Test PlansLast UpdatedTarget Completion DateReview StatusResults Summary
      + Modal Dialog Example V22.05.26 (11 Tests) + Jul 6, 2022Jan 2, 2023 +
      +
      + 97% +
      +
      97%
      +
      3 assertions failed across + 2 tests run with 1 browser +
      +
      +
      +
      +

      Review Status Summary

      +
      + + + + + + + + + + + + + + + + + +
      Test PlanJAWSNVDAVoiceOver for macOS
      Modal Dialog Example V22.05.26
      +
      +
      +
      + +
      + + + diff --git a/client/tests/e2e/snapshots/saved/_candidate-test-plan_24_1.html b/client/tests/e2e/snapshots/saved/_candidate-test-plan_24_1.html new file mode 100644 index 000000000..7c099f627 --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_candidate-test-plan_24_1.html @@ -0,0 +1,743 @@ + + + + + + + + + Candidate Test Run Page | ARIA-AT + + +
      +
      + +
      +
      +
      +
      + +
      +
      +
      +
      + Viewing Test Open a Modal Dialog in reading mode, Test 1 of + 18 +
      + Reviewing Test 1 of 18: +

      + 1. Open a Modal Dialog in reading mode + using JAWS 2021.2111.13 +

      +
      +
      +
      +
      + Candidate Test Plan: + Modal Dialog Example V22.05.26 +
      +
      +
      +
      + Review status by JAWS Representative: In Progress +
      +
      +
      +
      + Target Completion Date: January 2, 2023 +
      +
      +
      +
      +
      +
      +
      +
      +
      +

      + Open a Modal Dialog in reading mode +

      +
      +

      + +

      +
      +
        +
      1. + Configure JAWS with default settings. For + help, read + Configuring Screen Readers for Testing. +
      2. +
      3. + Activate the "Open test page" button, which + opens the example to test in a new window and + runs a script that sets focus on the 'Add + Delivery Address' button +
      4. +
      5. + With the reading cursor on the 'Add Delivery + Address' button, open the dialog. +
      6. +
      7. + With the reading cursor on the 'Add Delivery + Address' button, open the dialog. Do this with + each of the following commands or command + sequences. +
          +
        • Space
        • +
        • Enter
        • +
        +
      8. +
      +

      + Space: 4 MUST, 0 SHOULD, 0 MAY Assertions +

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      PriorityAssertion Statement
      MUSTRole 'dialog' is conveyed
      MUST + Name 'Add Delivery Address' is conveyed +
      MUST + Name of input ('Street') is conveyed +
      MUST + The ability to enter or edit text is + conveyed +
      +
      +

      + Enter: 4 MUST, 0 SHOULD, 0 MAY Assertions +

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      PriorityAssertion Statement
      MUSTRole 'dialog' is conveyed
      MUST + Name 'Add Delivery Address' is conveyed +
      MUST + Name of input ('Street') is conveyed +
      MUST + The ability to enter or edit text is + conveyed +
      +
      + +
      +

      + +

      +
      +

      + Test Results (12 passed, 0 failed) +

      +

      + Space Results: 6 passed, 0 failed +

      +

      + JAWS Response: +

      +
      + automatically seeded sample output +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + Space Results +
      PriorityAssertionResult
      MUSTRole 'dialog' is conveyedPassed
      MUST + Name 'Add Delivery Address' is conveyed + Passed
      MUST + Name of input ('Street') is conveyed + Passed
      MUST + The ability to enter or edit text is + conveyed + Passed
      MUST + Other behaviors that create severe + negative impacts are not exhibited + Passed
      SHOULD + Other behaviors that create moderate + negative impacts are not exhibited + Passed
      +
      + Other behaviors that create negative impact: None + +

      + Enter Results: 6 passed, 0 failed +

      +

      + JAWS Response: +

      +
      + automatically seeded sample output +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + Enter Results +
      PriorityAssertionResult
      MUSTRole 'dialog' is conveyedPassed
      MUST + Name 'Add Delivery Address' is conveyed + Passed
      MUST + Name of input ('Street') is conveyed + Passed
      MUST + The ability to enter or edit text is + conveyed + Passed
      MUST + Other behaviors that create severe + negative impacts are not exhibited + Passed
      SHOULD + Other behaviors that create moderate + negative impacts are not exhibited + Passed
      +
      + Other behaviors that create negative impact: None +
      +

      + +

      +
      +
        +
      • + Tested with JAWS 2021.2111.13 and + Chrome 99.0.4844.84 by + esmeralda-baggins +
      • +
      +
      +
      +
      +
      +
      +
        +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      +
      +
      +
      +
      +

      Test Review Options

      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      + + + diff --git a/client/tests/e2e/snapshots/saved/_data-management.html b/client/tests/e2e/snapshots/saved/_data-management.html new file mode 100644 index 000000000..496638791 --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_data-management.html @@ -0,0 +1,2593 @@ + + + + + + + + + Data Management | ARIA-AT + + +
      +
      + +
      +
      +
      +

      Data Management

      +

      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. +

      +
      +

      + +

      +
      +
      + Select an assistive technology and manage its versions in the + ARIA-AT App +
      +
      + +
      +
      +
      + +
      +
      + +
      +
      +
      +
      +
      +

      + +

      +
      +
      + Select a test plan, assistive technology and browser to add a + new test plan report to the test queue. +
      +
      + +
      +
      + +
      +
      +
      + +
      +
      + +
      +
      + +
      + +
      +
      +
      + +
      +
      + +
      +
      +
      +
      +
      +

      Test Plans Status Summary

      +
        + +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + + + R&D VersionDraft ReviewCandidate ReviewRecommended Version
      + Checkbox Example (Tri State) + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + Recommended +

      Since Jan 3, 2023

      +
      +
      N/A +
      + V23.08.23Review Completed Jul 6, 2022 +
      +
      +
      + V23.08.23Review Completed Jan 3, 2023 +
      +
      +
      + V23.08.23 +
      Approved Jan 3, 2023 +
      +
      + Modal Dialog Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + Candidate +

      Review Started Jul 6, 2022

      + +1 New Version in + Progress +
      +
      N/A +
      + V24.06.07 +
      +
      +
      +
      + V22.05.26 +
      0 Open + Issues +
      +
      None Yet
      + Alert Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + Draft +

      Review Started Jul 6, 2022

      + +1 New Version in + Progress +
      +
      +
      + V24.04.26 +
      +
      +
      + V22.04.14 +
      +
      +
      Not StartedNone Yet
      + Command Button Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + Draft +

      + Review Started Dec 14, 2023 +

      + +1 New Version in + Progress +
      +
      +
      + V24.03.12 +
      +
      +
      + V23.12.06 +
      +
      +
      Not StartedNone Yet
      + Select Only Combobox Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + Draft +

      Review Started Jul 6, 2022

      + +1 New Version in + Progress +
      +
      +
      + V22.03.17-1 +
      +
      +
      + V22.03.17 +
      +
      +
      Not StartedNone Yet
      + Toggle Button + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + Draft +

      Review Started Jul 6, 2022

      + +1 New Version in + Progress +
      +
      +
      + V24.03.12 +
      +
      +
      + V22.05.18 +
      +
      +
      Not StartedNone Yet
      + Action Menu Button Example Using aria-activedescendant + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Aug 21, 2024

      +
      +
      +
      + V24.08.21 +
      +
      Not StartedNot StartedNone Yet
      + Action Menu Button Example Using element.focus() + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Banner Landmark + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Breadcrumb Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Aug 23, 2023

      +
      +
      +
      + V23.08.23 +
      +
      Not StartedNot StartedNone Yet
      + Checkbox Example (Two State) + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Color Viewer Slider + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Jun 26, 2024

      +
      +
      +
      + V24.06.26 +
      +
      Not StartedNot StartedNone Yet
      + Combobox with Both List and Inline Autocomplete + Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 29, 2022

      +
      +
      +
      + V22.03.29-1 +
      +
      Not StartedNot StartedNone Yet
      + Complementary Landmark + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Contentinfo Landmark + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Data Grid Example 1: Minimal Data Grid + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Date Picker Spin Button Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Disclosure Navigation Menu Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Aug 12, 2024

      +
      +
      +
      + V24.08.12 +
      +
      Not StartedNot StartedNone Yet
      + Disclosure of Answers to Frequently Asked Questions + Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Editor Menubar Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Form Landmark + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Horizontal Multi-Thumb Slider + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Aug 23, 2023

      +
      +
      +
      + V23.08.23 +
      +
      Not StartedNot StartedNone Yet
      + Link Example 1 (span element with text content) + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Dec 13, 2023

      +
      +
      +
      + V23.12.13 +
      +
      Not StartedNot StartedNone Yet
      + Link Example 2 (img element with alt attribute) + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Aug 23, 2023

      +
      +
      +
      + V23.08.23 +
      +
      Not StartedNot StartedNone Yet
      + Link Example 3 (CSS :before content property on a span + element) + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Aug 23, 2023

      +
      +
      +
      + V23.08.23 +
      +
      Not StartedNot StartedNone Yet
      + Main Landmark + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Aug 5, 2022

      +
      +
      +
      + V22.08.05 +
      +
      Not StartedNot StartedNone Yet
      + Media Seek Slider + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Meter + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Aug 5, 2022

      +
      +
      +
      + V22.08.05 +
      +
      Not StartedNot StartedNone Yet
      + Navigation Menu Button + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete May 26, 2022

      +
      +
      +
      + V22.05.26 +
      +
      Not StartedNot StartedNone Yet
      + Radio Group Example Using Roving tabindex + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Aug 23, 2023

      +
      +
      +
      + V23.08.23 +
      +
      Not StartedNot StartedNone Yet
      + Radio Group Example Using aria-activedescendant + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 13, 2024

      +
      +
      +
      + V24.03.13 +
      +
      Not StartedNot StartedNone Yet
      + Rating Slider + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Switch Example + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Aug 5, 2022

      +
      +
      +
      + V22.08.05 +
      +
      Not StartedNot StartedNone Yet
      + Tabs with Manual Activation + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      + Vertical Temperature Slider + +
      + JAWS, NVDA and VoiceOver for macOS +
      +
      +
      + R&D +

      Complete Mar 17, 2022

      +
      +
      +
      + V22.03.17-1 +
      +
      Not StartedNot StartedNone Yet
      +
      +
      + Test Plans Status Summary Table, now sorted by Overall Status in + descending order +
      + + + diff --git a/client/tests/e2e/snapshots/saved/_data-management_meter.html b/client/tests/e2e/snapshots/saved/_data-management_meter.html new file mode 100644 index 000000000..7de71e1eb --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_data-management_meter.html @@ -0,0 +1,539 @@ + + + + + + + + + Meter Test Plan Versions | ARIA-AT + + +
      +
      + +
      +
      +
      +

      Meter Test Plan Versions

      + +

      Version Summary

      +
      + + + + + + + + + + + + + + + + + + + + +
      VersionLatest PhasePhase Change Date
      + V22.08.05 + R&DAug 5, 2022
      + V22.03.17 + + Deprecated before + Draft review + Aug 5, 2022
      +
      +
      +

      GitHub Issues

      +
      + No GitHub Issues +
      +
      +

      + Timeline for All Versions +

      +
      + + + + + + + + + + + + + + + + + + + + + +
      DateEvent
      Mar 17, 2022 + V22.03.17 R&D Complete +
      Aug 5, 2022 + V22.03.17 Deprecated +
      Aug 5, 2022 + V22.08.05 R&D Complete +
      +
      +
      +
      +

      + +

      +
      +
      +
      + +
      +
      Covered AT
      +
      +
        +
      • JAWS
      • +
      • NVDA
      • +
      • VoiceOver for macOS
      • +
      +
      +
      +

      + Timeline for V22.08.05 +

      +
      + + + + + + + + + + + + + +
      DateEvent
      Aug 5, 2022 + R&D Complete +
      +
      +
      +
      +
      +

      + +

      +
      +
      +
      + +
      +
      Covered AT
      +
      +
        +
      • JAWS
      • +
      • NVDA
      • +
      • VoiceOver for macOS
      • +
      +
      +
      +

      + Timeline for V22.03.17 +

      +
      + + + + + + + + + + + + + + + + + +
      DateEvent
      Mar 17, 2022 + R&D Complete +
      Aug 5, 2022 + Deprecated +
      +
      +
      +
      +
      +
      +
      +
      + +
      + + + diff --git a/client/tests/e2e/snapshots/saved/_reports.html b/client/tests/e2e/snapshots/saved/_reports.html new file mode 100644 index 000000000..21dc0c932 --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_reports.html @@ -0,0 +1,205 @@ + + + + + + + + + AT Interop Reports | ARIA-AT + + +
      +
      + +
      +
      +
      +

      Assistive Technology Interoperability Reports

      +

      Introduction

      +

      + This page offers a high-level view of all results which have been + collected, reviewed and published by the ARIA-AT project. Follow a + link in the table below to view detailed results. +

      +

      Support Levels

      +

      + The percentage of assertions which passed when each Test Plan was + executed by a given Assistive Technology and Browser. +

      +
      + + + + + + + + + + + + + + + + + + + + + + + +
      Test PlanJAWS and ChromeNVDA and ChromeVoiceOver for macOS and Safari
      + Checkbox Example (Mixed-State) + +
      +
      + 100% +
      +
      100%
      +
      +
      +
      +
      + 100% +
      +
      100%
      +
      +
      +
      +
      + 97% +
      +
      97%
      +
      +
      + Modal Dialog Example + +
      +
      + 97% +
      +
      97%
      +
      +
      +
      +
      + 97% +
      +
      97%
      +
      +
      +
      +
      + 97% +
      +
      97%
      +
      +
      +
      +
      +
      + +
      + + + diff --git a/client/tests/e2e/snapshots/saved/_run_2.html b/client/tests/e2e/snapshots/saved/_run_2.html new file mode 100644 index 000000000..c02c1c3ff --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_run_2.html @@ -0,0 +1,917 @@ + + + + + + + + + + Navigate forwards to a collapsed select-only combobox in reading mode for + NVDA 2020.4 and Firefox 99 | ARIA-AT + + + +
      +
      + +
      +
      +
      +
      +
      +
      +

      + +

      +
      + +
      +
      +
      +
      +

      + Test 1:Navigate forwards to + a collapsed select-only combobox in reading mode +

      +
      +
      +
      + Test Plan: Select Only Combobox Example +
      +
      +
      +
      +
      AT: NVDA 2020.4
      +
      + Browser: Firefox 99 +
      +
      + +
      +
      +
      + + 18 of 21 tests completed +
      +
      +
      +
      + Reviewing tests of esmeralda-baggins. +

      + All changes will be saved as performed by + esmeralda-baggins. +

      +
      +
      +
      +
      +
      +

      + Navigate forwards to a collapsed select-only + combobox in reading mode +

      +

      + Test Results (24 passed, 0 failed) +

      +

      F Results: 6 passed, 0 failed

      +

      + NVDA Response: +

      +
      + automatically seeded sample output +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + F Results +
      PriorityAssertionResult
      MUSTRole 'combobox' is conveyedPassed
      MUSTName 'Favorite Fruit' is conveyedPassed
      MUST + Text of the selected option ('Choose a + Fruit') is conveyed + Passed
      MUST + State of the combobox (collapsed) is + conveyed + Passed
      MUST + Other behaviors that create severe negative + impacts are not exhibited + Passed
      SHOULD + Other behaviors that create moderate + negative impacts are not exhibited + Passed
      +
      + Other behaviors that create negative impact: None + +

      C Results: 6 passed, 0 failed

      +

      + NVDA Response: +

      +
      + automatically seeded sample output +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + C Results +
      PriorityAssertionResult
      MUSTRole 'combobox' is conveyedPassed
      MUSTName 'Favorite Fruit' is conveyedPassed
      MUST + Text of the selected option ('Choose a + Fruit') is conveyed + Passed
      MUST + State of the combobox (collapsed) is + conveyed + Passed
      MUST + Other behaviors that create severe negative + impacts are not exhibited + Passed
      SHOULD + Other behaviors that create moderate + negative impacts are not exhibited + Passed
      +
      + Other behaviors that create negative impact: None + +

      + Tab Results: 6 passed, 0 failed +

      +

      + NVDA Response: +

      +
      + automatically seeded sample output +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + Tab Results +
      PriorityAssertionResult
      MUSTRole 'combobox' is conveyedPassed
      MUSTName 'Favorite Fruit' is conveyedPassed
      MUST + Text of the selected option ('Choose a + Fruit') is conveyed + Passed
      MUST + State of the combobox (collapsed) is + conveyed + Passed
      MUST + Other behaviors that create severe negative + impacts are not exhibited + Passed
      SHOULD + Other behaviors that create moderate + negative impacts are not exhibited + Passed
      +
      + Other behaviors that create negative impact: None + +

      + Down Arrow Results: 6 passed, 0 + failed +

      +

      + NVDA Response: +

      +
      + automatically seeded sample output +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + Down Arrow Results +
      PriorityAssertionResult
      MUSTRole 'combobox' is conveyedPassed
      MUSTName 'Favorite Fruit' is conveyedPassed
      MUST + Text of the selected option ('Choose a + Fruit') is conveyed + Passed
      MUST + State of the combobox (collapsed) is + conveyed + Passed
      MUST + Other behaviors that create severe negative + impacts are not exhibited + Passed
      SHOULD + Other behaviors that create moderate + negative impacts are not exhibited + Passed
      +
      + Other behaviors that create negative impact: None +
      +
      +
      +

      + Test Controls +

      +
        +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      • + +
      • +
      +
      +
      +
      +
      +

      Test Options

      + +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      + + + + + + diff --git a/client/tests/e2e/snapshots/saved/_signup-instructions.html b/client/tests/e2e/snapshots/saved/_signup-instructions.html new file mode 100644 index 000000000..aa808af49 --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_signup-instructions.html @@ -0,0 +1,91 @@ + + + + + + + + + ARIA-AT App + + +
      +
      + +
      +
      +
      +

      + You are not yet registered to participate! Let us know you want to + help by opening an issue on GitHub. +

      +
      +
      + +
      + + + diff --git a/client/tests/e2e/snapshots/saved/_test-plan-report_1.html b/client/tests/e2e/snapshots/saved/_test-plan-report_1.html new file mode 100644 index 000000000..2b5fee7c7 --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_test-plan-report_1.html @@ -0,0 +1,1476 @@ + + + + + + + + + + Navigate forwards to a not pressed toggle button in reading mode for JAWS + 2021.2111.13 and Chrome 99 | ARIA-AT + + + +
      +
      + +
      +
      +
      +
      + +
      +
      +
      +

      + Test 1:Navigate forwards to + a not pressed toggle button in reading mode +

      +
      +
      +
      + Test Plan: Toggle Button +
      +
      +
      +
      +
      AT: JAWS
      +
      Browser: Chrome
      +
      +
      +
      +
      + 16 tests to view +
      +
      +
      +
      +
      +
      +
      +
      +

      Test cannot be performed due to error(s)!

      +
        +
        +
        +
        +

        + Instructions +

        +
          +
        1. + Configure JAWS with default settings. For help, + read + Configuring Screen Readers for Testing. +
        2. +
        3. + Activate the "Open test page" button, which + opens the example to test in a new window and + runs a script that sets focus on a link before + the button +
        4. +
        5. + With the reading cursor on the 'Navigate + forwards from here' link, navigate to the 'Mute' + button. +
        6. +
        7. + With the reading cursor on the 'Navigate + forwards from here' link, navigate to the 'Mute' + button. Do this with each of the following + commands or command sequences. +
            +
          • Down Arrow
          • +
          • B
          • +
          • F
          • +
          • Tab
          • +
          +
        8. +
        + +
        +
        +

        Record Results

        +

        + Navigate forwards to a not pressed toggle button + in reading mode +

        +

        After 'Down Arrow'

        +
        + +
        + +
        + +
        +
        + + Which statements are true about the response to + Down Arrow? + +
        + Role 'button' is conveyed + +
        +
        + Name 'Mute' is conveyed + +
        +
        + State 'not pressed' is conveyed + +
        +
        +
        + + Were there additional undesirable behaviors? + +
        + +
        +
        + +
        + +
        +

        After 'B'

        +
        + +
        + +
        + +
        +
        + + Which statements are true about the response to + B? + +
        + Role 'button' is conveyed + +
        +
        + Name 'Mute' is conveyed + +
        +
        + State 'not pressed' is conveyed + +
        +
        +
        + + Were there additional undesirable behaviors? + +
        + +
        +
        + +
        + +
        +

        After 'F'

        +
        + +
        + +
        + +
        +
        + + Which statements are true about the response to + F? + +
        + Role 'button' is conveyed + +
        +
        + Name 'Mute' is conveyed + +
        +
        + State 'not pressed' is conveyed + +
        +
        +
        + + Were there additional undesirable behaviors? + +
        + +
        +
        + +
        + +
        +

        After 'Tab'

        +
        + +
        + +
        + +
        +
        + + Which statements are true about the response to + Tab? + +
        + Role 'button' is conveyed + +
        +
        + Name 'Mute' is conveyed + +
        +
        + State 'not pressed' is conveyed + +
        +
        +
        + + Were there additional undesirable behaviors? + +
        + +
        +
        + +
        + +
        +
        + +
        +
        +
        +

        + Test Controls +

        +
          +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        +
        +
        +
        +
        +

        Test Options

        + +
        +
        +
        +
        +
        +
        +
        +
        +
        +
        + +
        + + + diff --git a/client/tests/e2e/snapshots/saved/_test-queue.html b/client/tests/e2e/snapshots/saved/_test-queue.html new file mode 100644 index 000000000..867744847 --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_test-queue.html @@ -0,0 +1,1765 @@ + + + + + + + + + Test Queue | ARIA-AT + + +
        +
        + +
        +
        +
        +

        Test Queue

        +

        + Manage the test plans, assign yourself a test plan or start + executing one that is already assigned to you. +

        +
        +

        + +

        +
        +
        + Select an assistive technology and manage its versions in the + ARIA-AT App +
        +
        + +
        +
        +
        + +
        +
        + +
        +
        +
        +
        +
        +

        + +

        +
        +
        + Select a test plan, assistive technology and browser to add a + new test plan report to the test queue. +
        +
        + +
        +
        + +
        +
        +
        + +
        +
        + +
        +
        + +
        + +
        +
        +
        + +
        +
        + +
        +
        +
        +
        +
        +

        Alert Example

        +
        +

        + +

        +
        +
        + View tests in V22.04.14 +
        +
        +
        + + + + + + + + + + + + + + + + + + + +
        Assistive TechnologyBrowserTestersStatusActions
        +
        + VoiceOver for macOS 11.6 (20G165) or later +
        +
        +
        + Firefox Any version +
        +
        +
        + + +
        +
          +
          +
          +
          +
          +
          +
          + No testers assigned +
          +
          +
          + + + +
          +
          +
          +
          +
          + +
          +

          + +

          +
          +
          + View tests in V24.06.07 +
          +
          +
          + + + + + + + + + + + + + + + + + + + +
          Assistive TechnologyBrowserTestersStatusActions
          +
          + NVDA 2020.4 or later +
          +
          +
          + Chrome Any version +
          +
          +
          + + +
          + +
          +
          +
          +
          +
          +
          + 100% complete by esmeralda-baggins with 0 conflicts +
          +
          +
          + + + +
          +
          +
          +
          +

          + +

          +
          +
          + View tests in V22.05.26 +
          +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          Assistive TechnologyBrowserTestersStatusActions
          +
          + JAWS 2021.2111.13 or later +
          +
          +
          + Firefox Any version +
          +
          +
          + + +
          + +
          +
          +
          +
          +
          +
          + 100% complete by esmeralda-baggins with 0 conflicts +
          +
          +
          + + + +
          +
          +
          + NVDA 2020.4 or later +
          +
          +
          + Firefox Any version +
          +
          +
          + + +
          + +
          +
          +
          +
          +
          +
          + 100% complete by esmeralda-baggins with 0 conflicts +
          +
          +
          + + + +
          +
          +
          + VoiceOver for macOS 11.6 (20G165) or later +
          +
          +
          + Chrome Any version +
          +
          +
          + + +
          + +
          +
          +
          +
          +
          +
          + 100% complete by esmeralda-baggins with 0 conflicts +
          +
          +
          + + + +
          +
          +
          + VoiceOver for macOS 11.6 (20G165) or later +
          +
          +
          + Firefox Any version +
          +
          +
          + + +
          + +
          +
          +
          +
          +
          +
          + 100% complete by esmeralda-baggins with 0 conflicts +
          +
          +
          + + + +
          +
          +
          +
          +
          +

          + Select Only Combobox Example +

          +
          +

          + +

          +
          +
          + View tests in V22.03.17 +
          +
          +
          + + + + + + + + + + + + + + + + + + + +
          Assistive TechnologyBrowserTestersStatusActions
          +
          + NVDA 2020.4 or later +
          +
          +
          + Firefox Any version +
          +
          +
          + + +
          + +
          +
          +
          +
          +
          +
          + 85% complete by 2 testers with + 3 conflicts +
          +
          +
          + + + +
          +
          +
          +
          +
          +

          Toggle Button

          +
          +

          + +

          +
          +
          + View tests in V22.05.18 +
          +
          +
          + + + + + + + + + + + + + + + + + + + +
          Assistive TechnologyBrowserTestersStatusActions
          +
          + JAWS 2021.2111.13 or later +
          +
          +
          + Chrome Any version +
          +
          +
          + + +
          + +
          +
          +
          +
          +
          +
          + 75% complete by esmeralda-baggins with 0 conflicts +
          +
          +
          + + + +
          +
          +
          +
          +
          +
          +
          + +
          + + + diff --git a/client/tests/e2e/snapshots/saved/_test-review_8.html b/client/tests/e2e/snapshots/saved/_test-review_8.html new file mode 100644 index 000000000..03df550a9 --- /dev/null +++ b/client/tests/e2e/snapshots/saved/_test-review_8.html @@ -0,0 +1,1541 @@ + + + + + + + + + Command Button Example Test Plan V22.05.04 | ARIA-AT + + +
          +
          + +
          +
          +
          +

          Command Button Example Test Plan V22.05.04 (Deprecated)

          +

          About This Test Plan

          + +

          Supporting Documentation

          + +

          Tests

          +
          +
            + +
          • + +
          • +
          • + +
          • +
          • + +
          • +
          • + +
          • +
          +
          +

          Test 1: Navigate forwards to a button in reading mode

          +

          JAWS

          +
          Instructions
          +
            +
          1. + Configure JAWS with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on a link + before the button +
          4. +
          5. + With the reading cursor on the 'Navigate forwards from here' link, + navigate to the 'Print Page' button +
          6. +
          7. + With the reading cursor on the 'Navigate forwards from here' link, + navigate to the 'Print Page' button Do this with each of the + following commands or command sequences. +
              +
            • Down Arrow
            • +
            • B
            • +
            • F
            • +
            • Tab
            • +
            +
          8. +
          +
          + Down Arrow: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          B: 2 MUST, 0 SHOULD, 0 MAY Assertions
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          F: 2 MUST, 0 SHOULD, 0 MAY Assertions
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +

          NVDA

          +
          Instructions
          +
            +
          1. + Configure NVDA with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on a link + before the button +
          4. +
          5. + With the reading cursor on the 'Navigate forwards from here' link, + navigate to the 'Print Page' button +
          6. +
          7. + With the reading cursor on the 'Navigate forwards from here' link, + navigate to the 'Print Page' button Do this with each of the + following commands or command sequences. +
              +
            • Down Arrow
            • +
            • B
            • +
            • F
            • +
            • Tab
            • +
            +
          8. +
          +
          + Down Arrow: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          B: 2 MUST, 0 SHOULD, 0 MAY Assertions
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          F: 2 MUST, 0 SHOULD, 0 MAY Assertions
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +
          +

          Test 2: Navigate backwards to a button in reading mode

          +

          JAWS

          +
          Instructions
          +
            +
          1. + Configure JAWS with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on a link + after the button +
          4. +
          5. + With the reading cursor on the 'Navigate backwards from here' + link, navigate to the 'Print Page' button +
          6. +
          7. + With the reading cursor on the 'Navigate backwards from here' + link, navigate to the 'Print Page' button Do this with each of the + following commands or command sequences. +
              +
            • Up Arrow
            • +
            • Shift+B
            • +
            • Shift+F
            • +
            • Shift+Tab
            • +
            +
          8. +
          +
          + Up Arrow: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Shift+B: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Shift+F: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Shift+Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +

          NVDA

          +
          Instructions
          +
            +
          1. + Configure NVDA with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on a link + after the button +
          4. +
          5. + With the reading cursor on the 'Navigate backwards from here' + link, navigate to the 'Print Page' button +
          6. +
          7. + With the reading cursor on the 'Navigate backwards from here' + link, navigate to the 'Print Page' button Do this with each of the + following commands or command sequences. +
              +
            • Up Arrow
            • +
            • Shift+B
            • +
            • Shift+F
            • +
            • Shift+Tab
            • +
            +
          8. +
          +
          + Up Arrow: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Shift+B: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Shift+F: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Shift+Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +
          +

          Test 3: Navigate forwards to a button in interaction mode

          +

          JAWS

          +
          Instructions
          +
            +
          1. + Configure JAWS with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on a link + before the button +
          4. +
          5. + With focus on the 'navigate forwards from here' link, navigate to + the 'Print Page' button. +
          6. +
          7. + With focus on the 'navigate forwards from here' link, navigate to + the 'Print Page' button. Do this with each of the following + commands or command sequences. +
              +
            • Tab
            • +
            +
          8. +
          +
          + Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +

          NVDA

          +
          Instructions
          +
            +
          1. + Configure NVDA with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on a link + before the button +
          4. +
          5. + With focus on the 'navigate forwards from here' link, navigate to + the 'Print Page' button. +
          6. +
          7. + With focus on the 'navigate forwards from here' link, navigate to + the 'Print Page' button. Do this with each of the following + commands or command sequences. +
              +
            • Tab
            • +
            +
          8. +
          +
          + Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +
          +

          Test 4: Navigate backwards to a button in interaction mode

          +

          JAWS

          +
          Instructions
          +
            +
          1. + Configure JAWS with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on a link + after the button +
          4. +
          5. + With focus on the 'Navigate backwards from here' link, navigate to + the 'Print Page' button. +
          6. +
          7. + With focus on the 'Navigate backwards from here' link, navigate to + the 'Print Page' button. Do this with each of the following + commands or command sequences. +
              +
            • Shift+Tab
            • +
            +
          8. +
          +
          + Shift+Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +

          NVDA

          +
          Instructions
          +
            +
          1. + Configure NVDA with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on a link + after the button +
          4. +
          5. + With focus on the 'Navigate backwards from here' link, navigate to + the 'Print Page' button. +
          6. +
          7. + With focus on the 'Navigate backwards from here' link, navigate to + the 'Print Page' button. Do this with each of the following + commands or command sequences. +
              +
            • Shift+Tab
            • +
            +
          8. +
          +
          + Shift+Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +
          +

          Test 5: Navigate forwards to a button

          +

          VoiceOver for macOS

          +
          Instructions
          +
            +
          1. + Configure VoiceOver for macOS with default settings. For help, + read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on a link + before the button +
          4. +
          5. + With focus on the 'Navigate forwards from here' link, navigate to + the 'Print Page' button. +
          6. +
          7. + With focus on the 'Navigate forwards from here' link, navigate to + the 'Print Page' button. Do this with each of the following + commands or command sequences. +
              +
            • Control+Option+Right
            • +
            • Tab
            • +
            • Control+Option+Command+J
            • +
            +
          8. +
          +
          + Control+Option+Right: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Control+Option+Command+J: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +
          +

          Test 6: Navigate backwards to a button

          +

          VoiceOver for macOS

          +
          Instructions
          +
            +
          1. + Configure VoiceOver for macOS with default settings. For help, + read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on a link + after the button +
          4. +
          5. + With focus on the 'Navigate backwards from here' link, navigate to + the 'Print Page' button. +
          6. +
          7. + With focus on the 'Navigate backwards from here' link, navigate to + the 'Print Page' button. Do this with each of the following + commands or command sequences. +
              +
            • Ctrl+Option+Left
            • +
            • Shift+Tab
            • +
            • Shift+Control+Option+Command+J
            • +
            +
          8. +
          +
          + Ctrl+Option+Left: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Shift+Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Shift+Control+Option+Command+J: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +
          +

          Test 7: Read information about a button in reading mode

          +

          JAWS

          +
          Instructions
          +
            +
          1. + Configure JAWS with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on the + button +
          4. +
          5. + With the reading cursor on the 'Print Page' button, read + information about the button. +
          6. +
          7. + With the reading cursor on the 'Print Page' button, read + information about the button. Do this with each of the following + commands or command sequences. +
              +
            • Insert+Tab
            • +
            • Insert+Up
            • +
            +
          8. +
          +
          + Insert+Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Insert+Up: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +

          NVDA

          +
          Instructions
          +
            +
          1. + Configure NVDA with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on the + button +
          4. +
          5. + With the reading cursor on the 'Print Page' button, read + information about the button. +
          6. +
          7. + With the reading cursor on the 'Print Page' button, read + information about the button. Do this with each of the following + commands or command sequences. +
              +
            • Insert+Tab
            • +
            • Insert+Up
            • +
            +
          8. +
          +
          + Insert+Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Insert+Up: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +
          +

          Test 8: Read information about a button in interaction mode

          +

          JAWS

          +
          Instructions
          +
            +
          1. + Configure JAWS with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on the + button +
          4. +
          5. + With focus on the 'Print Page' button, read information about the + button. +
          6. +
          7. + With focus on the 'Print Page' button, read information about the + button. Do this with each of the following commands or command + sequences. +
              +
            • Insert+Tab
            • +
            • Insert+Up
            • +
            +
          8. +
          +
          + Insert+Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Insert+Up: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +

          NVDA

          +
          Instructions
          +
            +
          1. + Configure NVDA with default settings. For help, read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on the + button +
          4. +
          5. + With focus on the 'Print Page' button, read information about the + button. +
          6. +
          7. + With focus on the 'Print Page' button, read information about the + button. Do this with each of the following commands or command + sequences. +
              +
            • Insert+Tab
            • +
            • Insert+Up
            • +
            +
          8. +
          +
          + Insert+Tab: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Insert+Up: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +
          +

          Test 9: Read information about a button

          +

          VoiceOver for macOS

          +
          Instructions
          +
            +
          1. + Configure VoiceOver for macOS with default settings. For help, + read + Configuring Screen Readers for Testing. +
          2. +
          3. + Activate the "Open test page" button, which opens the example to + test in a new window and runs a script that sets focus on the + button +
          4. +
          5. + With focus on the 'Print Page' button, read information about the + button. +
          6. +
          7. + With focus on the 'Print Page' button, read information about the + button. Do this with each of the following commands or command + sequences. +
              +
            • Control+Option+F3
            • +
            • Control+Option+F4
            • +
            +
          8. +
          +
          + Control+Option+F3: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          +
          + Control+Option+F4: 2 MUST, 0 SHOULD, 0 MAY Assertions +
          +
          + + + + + + + + + + + + + + + + + +
          PriorityAssertion Statement
          MUSTRole 'button' is conveyed
          MUSTName 'Print Page' is conveyed
          +
          + +
          +
          + +
          + + + diff --git a/client/tests/e2e/snapshots/snapshotTest.e2e.test.js b/client/tests/e2e/snapshots/snapshotTest.e2e.test.js new file mode 100644 index 000000000..9deeeb00a --- /dev/null +++ b/client/tests/e2e/snapshots/snapshotTest.e2e.test.js @@ -0,0 +1,28 @@ +import fs from 'fs/promises'; +import path from 'path'; +import { + snapshotRoutes, + cleanAndNormalizeSnapshot, + routeToSnapshotFilename +} from './utils'; +import getPage from '../../util/getPage'; + +const SNAPSHOTS_DIR = path.join(__dirname, 'saved'); + +describe('Snapshot Comparison', () => { + snapshotRoutes.forEach(route => { + test(`should match snapshot for ${route}`, async () => { + await getPage({ role: 'admin', url: route }, async page => { + await page.waitForSelector('main'); + + const currentSnapshot = await cleanAndNormalizeSnapshot(page); + + const fileName = routeToSnapshotFilename(route); + const snapshotPath = path.join(SNAPSHOTS_DIR, fileName); + + const existingSnapshot = await fs.readFile(snapshotPath, 'utf-8'); + expect(currentSnapshot.trim()).toBe(existingSnapshot.trim()); + }); + }); + }); +}); diff --git a/client/tests/e2e/snapshots/takeSnapshots.js b/client/tests/e2e/snapshots/takeSnapshots.js new file mode 100644 index 000000000..4e0094ab1 --- /dev/null +++ b/client/tests/e2e/snapshots/takeSnapshots.js @@ -0,0 +1,52 @@ +/* eslint-disable no-console */ +const fs = require('fs').promises; +const path = require('path'); +const getPage = require('../../util/getPage'); +const { setup, teardown } = require('../../util/getPage'); +const { + snapshotRoutes, + cleanAndNormalizeSnapshot, + routeToSnapshotFilename +} = require('./utils'); + +const SNAPSHOTS_DIR = path.join(__dirname, 'saved'); + +async function takeSnapshot(browser, role, route) { + console.log(`Taking snapshot for ${route}`); + try { + let snapshot; + await getPage({ role, url: route }, async page => { + await page.waitForSelector('main'); + + snapshot = await cleanAndNormalizeSnapshot(page); + }); + + return snapshot; + } catch (error) { + console.warn(`Error taking snapshot for ${route}:`, error); + return null; + } +} + +async function takeSnapshots() { + try { + const browser = await setup(); + global.browser = browser; + + for (const route of snapshotRoutes) { + const snapshot = await takeSnapshot(browser, 'admin', route); + if (!snapshot) { + continue; + } + const fileName = routeToSnapshotFilename(route); + await fs.writeFile(path.join(SNAPSHOTS_DIR, fileName), snapshot); + console.log(`Recorded snapshot for ${route}`); + } + } catch (e) { + console.warn('Error during snapshot:', e); + } finally { + await teardown(); + } +} + +takeSnapshots().catch(console.error); diff --git a/client/tests/e2e/snapshots/utils.js b/client/tests/e2e/snapshots/utils.js new file mode 100644 index 000000000..259e3bf10 --- /dev/null +++ b/client/tests/e2e/snapshots/utils.js @@ -0,0 +1,99 @@ +const prettier = require('prettier'); + +const snapshotRoutes = [ + '/', + '/signup-instructions', + '/account/settings', + '/test-queue', + '/reports', + '/candidate-review', + '/data-management', + '/404', + '/test-plan-report/1', + '/test-review/8', + '/run/2', + '/data-management/meter', + '/candidate-test-plan/24/1' +]; + +async function cleanAndNormalizeSnapshot(page) { + // Remove all