-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add trip summary a11y label (#52)
* feat: add trip summary a11y label Reused the code for the trip summary from the app. Need to clean up usage of helper functions, usage of types etc. * refacor: use existing function for translated transport mode * refactor: update import path * test: add tests for `tripSummary` * test: fix tests failing due to time zone
- Loading branch information
1 parent
e32956b
commit 9420c68
Showing
9 changed files
with
768 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const screenReaderPause = '.\n'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { TripPattern } from '../../server/journey-planner/validators'; | ||
|
||
export const tripFixture: TripPattern = { | ||
expectedStartTime: '2023-01-01T00:00:00+01:00', | ||
expectedEndTime: '2023-01-01T01:00:00+01:00', | ||
duration: 3600, | ||
walkDistance: 0, | ||
legs: [ | ||
{ | ||
mode: 'bus', | ||
distance: 1, | ||
duration: 1, | ||
aimedStartTime: '2023-01-01T00:00:00+01:00', | ||
aimedEndTime: '2023-01-01T01:00:00+01:00', | ||
expectedEndTime: '2023-01-01T01:00:00+01:00', | ||
expectedStartTime: '2023-01-01T00:00:00+01:00', | ||
realtime: false, | ||
transportSubmode: 'regionalBus', | ||
line: { | ||
id: 'ATB:Line:1', | ||
name: 'Line', | ||
transportSubmode: 'regionalBus', | ||
publicCode: '1', | ||
flexibleLineType: null, | ||
notices: [], | ||
}, | ||
fromEstimatedCall: { | ||
aimedDepartureTime: '2023-01-01T00:00:00+01:00', | ||
expectedDepartureTime: '2023-01-01T01:00:00+01:00', | ||
destinationDisplay: { | ||
frontText: 'Destination', | ||
}, | ||
quay: { | ||
publicCode: '', | ||
name: 'Quay', | ||
}, | ||
notices: [], | ||
}, | ||
situations: [], | ||
fromPlace: { | ||
name: 'From', | ||
longitude: 0, | ||
latitude: 0, | ||
quay: { | ||
publicCode: '1', | ||
name: 'From', | ||
id: 'NSR:Quay:1', | ||
situations: [], | ||
}, | ||
}, | ||
toPlace: { | ||
name: '2', | ||
longitude: 0, | ||
latitude: 0, | ||
quay: { | ||
publicCode: '2', | ||
name: '2', | ||
id: 'NSR:Quay:2', | ||
situations: [], | ||
}, | ||
}, | ||
serviceJourney: { | ||
id: 'ATB:ServiceJourney:1', | ||
notices: [], | ||
journeyPattern: { | ||
notices: [], | ||
}, | ||
}, | ||
rentedBike: null, | ||
interchangeTo: null, | ||
pointsOnLink: { | ||
points: | ||
'yscbKgbqfAaJzl@oEx^??oAdKi@zDc@hBaAjC_@t@aA`BeUn]kApBg@pAo@jCa@bCWlCEt@e@tJ??sBpe@WlEQ|Bs@bGq@vD??_DpMsAhF{@dCy@dBgDtG??gA`Cw@rBc@jB[vBQvBEpB@~Bp@nM??LjEL`P\\da@J|EThGlAfV??TdFH`D?fC_Av_@CzB??AnCJhe@??@|RG`ZBtFP`Ij@bM??DfC?zBGxCUdD_@dDm@jDa@|Ai@`B}ArDw@`Ce@xBKt@oAhLiAjIUhECtCF~BTjD^pCPz@bBxGJb@FET\\??U]GDj@xDThCFlBD~C?xFCzAKjBOnAMx@cAtEiBxK]zAcB`G]bBs@fFY`C??y@bIc@nFMnCa@xLQdDIdAS~AQfASx@sAtEkAtEgArDwF~Qg@vA{@zAeE|FgFjGwA~Bk@lAa@`Aa@lAa@|Am@bDe@hD_@jF_AtNM|AOtA_@vBWjAaBbG??gFfRk@dC_@~BKrAGhBAnCD`BPbCx@dFTjBThCH`BD|BBxMRlOA~BIbC_@fFq@vGo@fEgChOk@zCu@xCeDfL{Ir_@k@pCm@vB}A`Hq@|DUjBMjBKdDA`CJvLHlGFpBHjBv@hLF~ABxB?vAGrCY~FW|CeB|PWvCOzDQ~MS|FYlE}@dJQ~CGnEBhLCtEe@z\\KxEKtCYnEa@`EYbC_@tBoAfF{@pEKI??nl@t~KCA]xEWtFG|BI|G@rKD`GH~BPjBnAzHRrBd@`HVxBPfAXjA|AtFd@hBPhARbBLzBFvC?`AEtAMrAS`A[|@_IzQc@pAw@fDoGdZeAzF[jCQxBO~BIlCoAns@??CzCBvCNbFJpBpArPHdBFhB@tBElAq@tLObEaAhl@D@JTFV@\\A^??Mp@SGKxFCnDFvDFnAj@pIF~C?x@ElBKpBMlA{CfWWpCEz@MCONCPE|@???lA\\F?|@HvDZzFHdA^~Bt@nDtAtH~@~FtA~JLrALrBHhD@vBh@rmBEjGu@|i@C|B@`CN`FLrCZvGV|D`@fFtF~n@P`CHnBJfDDfC@vCEfCEvAOdCQjBw@~F??sDxWs@zGMfBI~BEfFHzG??h@zPH~ALlAT`BVfA^rA`BdEp@pBxCdLf@~Az@vBpDjHd@v@j@t@nDhD|AjBvAxBvDtG~FvI|@z@x@d@|HbDvA~@v@t@t@`AbCbEdAvB`A`CbAnCfBzFjAjEh@~B`AfFbA|G]d@Lt@??PfAHHRMl@jG^pFjEbq@TlDL`D??ZpJD`EAlE}@nlCEjBGzAQnBUpB[lB[xA[`AGQwgBx{DJHePvaB{@nJyAlRW[EU??DTVZcEhi@??Q~B]xGOdEc@rQc@rTO~OAtCDhIx@`a@??P~YF~DJjE~@zY`@pKd@dKx@lMbDj`@J`BRGFFB\\@tBA?aOrgCLHM`DGlCCbFDjDHbCJrB`@`F\\zCbAnGr@hFp@xG`@hFLhCJbDFrD@~B?~BEdCeBb_@QdE[fR??C`BA|FFjL?dBGfESbE_@zDsBjN[nDQvDGbE]BIzA??BbAd@S@n@^vJn@jLl@rH~@jI|ArKzA`IR|@v@|CrB|F^vA^bCNzBFnBDpD`@x]I?jStnC??yTngEEFEWMYqBzNyApLsB`RcBvPsAtOqIpkAk@rJUpFMzEIdEErICh@?v@RfJ@nBM^Aj@@PLb@DFFrBA|D@p@Dv@~@pMHjADJn@hH`@pFJzCFjEOdLIjN@rBCrIBdLIlCCFq@LaDG??kKW@xH??Jhm@p@AAxCDFj@?', | ||
length: 530, | ||
}, | ||
intermediateEstimatedCalls: [], | ||
authority: { | ||
id: 'ATB:Authority:2', | ||
}, | ||
serviceJourneyEstimatedCalls: null, | ||
datedServiceJourney: null, | ||
}, | ||
], | ||
}; |
212 changes: 212 additions & 0 deletions
212
src/page-modules/assistant/trip/__tests__/trip.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
import { cleanup, render, screen } from '@testing-library/react'; | ||
import mockRouter from 'next-router-mock'; | ||
import { afterEach, describe, expect, it, vi } from 'vitest'; | ||
import { createDynamicRouteParser } from 'next-router-mock/dynamic-routes'; | ||
import { tripFixture } from './trip.fixture'; | ||
import { | ||
AppCookiesProvider, | ||
AppCookiesProviderProps, | ||
} from '@atb/modules/cookies/cookies-context'; | ||
import React from 'react'; | ||
import { | ||
AppLanguageProvider, | ||
Language, | ||
useTranslation, | ||
} from '@atb/translations'; | ||
import { tripSummary } from '../utils'; | ||
import { formatToClock } from '@atb/utils/date'; | ||
|
||
afterEach(function () { | ||
cleanup(); | ||
}); | ||
|
||
vi.mock('next/router', () => require('next-router-mock')); | ||
|
||
mockRouter.useParser(createDynamicRouteParser(['/assistant'])); | ||
|
||
type RenderProps = { providerProps?: AppCookiesProviderProps }; | ||
const customRender = ( | ||
ui: React.ReactNode, | ||
{ | ||
providerProps = { | ||
initialCookies: { | ||
darkmode: false, | ||
language: 'no', | ||
}, | ||
}, | ||
...renderOptions | ||
}: RenderProps, | ||
) => { | ||
return render( | ||
<AppCookiesProvider {...providerProps}> | ||
<AppLanguageProvider serverAcceptLanguage="">{ui}</AppLanguageProvider> | ||
</AppCookiesProvider>, | ||
renderOptions, | ||
); | ||
}; | ||
|
||
describe('trip', function () { | ||
describe('trip summary', function () { | ||
it('should create correct summary', () => { | ||
const Test = function () { | ||
const { t, language } = useTranslation(); | ||
|
||
const summary = tripSummary(tripFixture, t, language, false, 1); | ||
return ( | ||
<div data-testid="test-id" aria-label={summary}> | ||
{summary} | ||
</div> | ||
); | ||
}; | ||
|
||
customRender(<Test />, {}); | ||
|
||
const ariaLabel = screen | ||
.getByTestId('test-id') | ||
.getAttribute('aria-label'); | ||
|
||
const startTime = formatToClock( | ||
tripFixture.expectedStartTime, | ||
Language.Norwegian, | ||
); | ||
const endTime = formatToClock( | ||
tripFixture.expectedEndTime, | ||
Language.Norwegian, | ||
); | ||
|
||
const expected = | ||
`Reiseresultat 1.\nBuss fra From 1.\nBussnummer 1.\nKlokken ${startTime}.\nIngen bytter.\nTotalt 0 meter å gå.` + | ||
`\nStart klokken ${startTime}, ankomst klokken ${endTime}. Total reisetid 1 time.`; | ||
|
||
expect(ariaLabel).toBe(expected); | ||
}); | ||
|
||
it('should create summary in English', () => { | ||
const Test = function () { | ||
const { t, language } = useTranslation(); | ||
|
||
const summary = tripSummary(tripFixture, t, language, false, 1); | ||
return ( | ||
<div data-testid="test-id" aria-label={summary}> | ||
{summary} | ||
</div> | ||
); | ||
}; | ||
|
||
customRender(<Test />, { | ||
providerProps: { | ||
initialCookies: { | ||
darkmode: false, | ||
language: 'en-US', | ||
}, | ||
}, | ||
}); | ||
|
||
const ariaLabel = screen | ||
.getByTestId('test-id') | ||
.getAttribute('aria-label'); | ||
|
||
const startTime = formatToClock( | ||
tripFixture.expectedStartTime, | ||
Language.Norwegian, | ||
); | ||
const endTime = formatToClock( | ||
tripFixture.expectedEndTime, | ||
Language.Norwegian, | ||
); | ||
|
||
const expected = | ||
`Result number 1.\nBus from From 1.\nBus number 1.\nAt ${startTime}.\nNo transfers.\nTotal of 0 meters to walk.` + | ||
`\nStart time ${startTime}, arrival time ${endTime}. Total travel time 1 hour`; | ||
|
||
expect(ariaLabel).toBe(expected); | ||
}); | ||
|
||
it('should create summary in nynorsk', () => { | ||
const Test = function () { | ||
const { t, language } = useTranslation(); | ||
|
||
const summary = tripSummary(tripFixture, t, language, false, 1); | ||
return ( | ||
<div data-testid="test-id" aria-label={summary}> | ||
{summary} | ||
</div> | ||
); | ||
}; | ||
|
||
customRender(<Test />, { | ||
providerProps: { | ||
initialCookies: { | ||
darkmode: false, | ||
language: 'nn', | ||
}, | ||
}, | ||
}); | ||
|
||
const ariaLabel = screen | ||
.getByTestId('test-id') | ||
.getAttribute('aria-label'); | ||
|
||
const startTime = formatToClock( | ||
tripFixture.expectedStartTime, | ||
Language.Norwegian, | ||
); | ||
const endTime = formatToClock( | ||
tripFixture.expectedEndTime, | ||
Language.Norwegian, | ||
); | ||
|
||
const expected = | ||
`Reiseresultat 1.\nBuss frå From 1.\nBussnummer 1.\nKlokka ${startTime}.\nIngen bytter.\nTotalt 0 meter å gå.` + | ||
`\nStart klokka ${startTime}, framkomst klokka ${endTime}. Total reisetid 1 time.`; | ||
|
||
expect(ariaLabel).toBe(expected); | ||
}); | ||
|
||
it('should create summary with trip in the past', () => { | ||
const Test = function () { | ||
const { t, language } = useTranslation(); | ||
|
||
const summary = tripSummary(tripFixture, t, language, true, 1); | ||
return ( | ||
<div data-testid="test-id" aria-label={summary}> | ||
{summary} | ||
</div> | ||
); | ||
}; | ||
|
||
customRender(<Test />, {}); | ||
|
||
const ariaLabel = screen | ||
.getByTestId('test-id') | ||
.getAttribute('aria-label'); | ||
|
||
const expected = 'Passert reise'; | ||
|
||
expect(ariaLabel).toContain(expected); | ||
}); | ||
|
||
it('should create summary with correct result number', () => { | ||
const Test = function () { | ||
const { t, language } = useTranslation(); | ||
|
||
const summary = tripSummary(tripFixture, t, language, true, 5); | ||
return ( | ||
<div data-testid="test-id" aria-label={summary}> | ||
{summary} | ||
</div> | ||
); | ||
}; | ||
|
||
customRender(<Test />, {}); | ||
|
||
const ariaLabel = screen | ||
.getByTestId('test-id') | ||
.getAttribute('aria-label'); | ||
|
||
const expected = 'Reiseresultat 5'; | ||
|
||
expect(ariaLabel).toContain(expected); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.