@@ -14,7 +14,7 @@ interface componentDSL {
1414
1515//Defines a domain-specific language (DSL) for checking assertions against the system under test (sut)
1616interface componentDSLAssertions {
17- thereAreTheFollowingSagaChangesInThisOrder ( sagaUpdates : { expectedTime : Date } [ ] ) : void ;
17+ thereAreTheFollowingSagaChangesInThisOrder ( expectedDatesInOrder : Date [ ] ) : void ;
1818 displayedSagaGuidIs ( sagaId : string ) : void ;
1919 displayedSagaNameIs ( humanizedSagaName : string ) : void ;
2020 linkIsShown ( arg0 : { withText : string ; withHref : string } ) : void ;
@@ -109,8 +109,15 @@ describe("Feature: 3 Visual Representation of Saga Timeline", () => {
109109 } ) ;
110110 } ) ;
111111
112- describe ( "Rule: 3.2 Display a chronological timeline of saga events in UTC." , ( ) => {
113- test ( "EXAMPLE: Rendering a Saga with 4 changes" , ( ) => {
112+ describe ( "Rule: 3.3 Display a chronological timeline of saga events localized to user environment." , ( ) => {
113+ test . each ( [
114+ {
115+ timezone : "UTC" ,
116+ } ,
117+ {
118+ timezone : "America/Los_Angeles" ,
119+ } ,
120+ ] ) ( "EXAMPLE: Rendering a Saga with 4 changes - User Timezone $timezone" , ( { timezone } ) => {
114121 // Each saga event ("Saga Initiated," "Saga Updated," "Timeout Invoked," "Saga Completed") is timestamped to represent progression over time. Events are ordered by the time they ocurred.
115122 //TODO: "Incoming messages are displayed on the left, and outgoing messages are displayed on the right." in another test?
116123
@@ -127,10 +134,10 @@ describe("Feature: 3 Visual Representation of Saga Timeline", () => {
127134
128135 // Set the environment to a fixed timezone
129136 // JSDOM, used by Vitest, defaults to UTC timezone
130- // To ensure consistency, explicitly set the timezone to UTC
137+ // To ensure consistency, explicitly set the timezone
131138 // This ensures that the rendered local time of the saga changes
132- // will always be interpreted and displayed in UTC , avoiding flakiness
133- process . env . TZ = "UTC" ;
139+ // will always be interpreted and displayed in the specified timezone , avoiding flakiness
140+ process . env . TZ = timezone ;
134141
135142 //access each of the saga changes and update its start time and finish time to the same values being read from the variable declaration,
136143 // but set them again explicitly here
@@ -168,92 +175,7 @@ describe("Feature: 3 Visual Representation of Saga Timeline", () => {
168175 } ) ;
169176
170177 //assert
171- componentDriver . assert . thereAreTheFollowingSagaChangesInThisOrder ( [
172- {
173- expectedTime : startTimeD ,
174- } ,
175- {
176- expectedTime : startTimeC ,
177- } ,
178- {
179- expectedTime : startTimeB ,
180- } ,
181- {
182- expectedTime : startTimeA ,
183- } ,
184- ] ) ;
185- } ) ;
186- } ) ;
187- describe ( "Rule: 3.3 Display a chronological timeline of saga events in PST." , ( ) => {
188- test ( "EXAMPLE: Rendering a Saga with 4 changes" , ( ) => {
189- // Each saga event ("Saga Initiated," "Saga Updated," "Timeout Invoked," "Saga Completed") is timestamped to represent progression over time. Events are ordered by the time they ocurred.
190- //TODO: "Incoming messages are displayed on the left, and outgoing messages are displayed on the right." in another test?
191-
192- //arragement
193- //sampleSagaHistory already not sorted TODO: Make this more clear so the reader of this test doesn't have to go arround and figure out the preconditions
194- const messageStore = { } as MessageStore ;
195- messageStore . state = { } as MessageStore [ "state" ] ;
196- messageStore . state . data = { } as MessageStore [ "state" ] [ "data" ] ;
197- messageStore . state . data . invoked_saga = {
198- has_saga : true ,
199- saga_id : "123" ,
200- saga_type : "ServiceControl.SmokeTest.AuditingSaga" ,
201- } ;
202-
203- // Set the environment to a fixed timezone
204- // JSDOM, used by Vitest, defaults to PST timezone
205- // To ensure consistency, explicitly set the timezone to PST
206- // This ensures that the rendered local time of the saga changes
207- // will always be interpreted and displayed in "America/Los_Angeles"
208- process . env . TZ = "America/Los_Angeles" ;
209-
210- //access each of the saga changes and update its start time and finish time to the same values being read from the variable declaration,
211- // but set them again explicitly here
212- //so that the reader of this test can see the preconditions at play
213- //and understand the test better without having to jump around
214- const startTimeA = new Date ( "2025-03-28T03:04:08.000Z" ) ;
215- const finishTimeA1 = new Date ( "2025-03-28T03:04:08.000Z" ) ;
216- const startTimeB = new Date ( "2025-03-28T03:04:07.000Z" ) ;
217- const finishTimeB1 = new Date ( "2025-03-28T03:04:07.000Z" ) ;
218- const startTimeC = new Date ( "2025-03-28T03:04:06.000Z" ) ;
219- const finishTimeC1 = new Date ( "2025-03-28T03:04:06.000Z" ) ;
220- const startTimeD = new Date ( "2025-03-28T03:04:05.000Z" ) ;
221- const finishTimeD1 = new Date ( "2025-03-28T03:04:05.000Z" ) ;
222-
223- sampleSagaHistory . changes [ 0 ] . start_time = startTimeA ;
224- sampleSagaHistory . changes [ 0 ] . finish_time = finishTimeA1 ;
225- sampleSagaHistory . changes [ 1 ] . start_time = startTimeB ;
226- sampleSagaHistory . changes [ 1 ] . finish_time = finishTimeB1 ;
227- sampleSagaHistory . changes [ 2 ] . start_time = startTimeC ;
228- sampleSagaHistory . changes [ 2 ] . finish_time = finishTimeC1 ;
229- sampleSagaHistory . changes [ 3 ] . start_time = startTimeD ;
230- sampleSagaHistory . changes [ 3 ] . finish_time = finishTimeD1 ;
231- sampleSagaHistory . changes [ 3 ] . status = "new" ;
232-
233- // Set up the store with sample saga history
234- const componentDriver = rendercomponent ( {
235- initialState : {
236- MessageStore : messageStore ,
237- SagaDiagramStore : { sagaHistory : sampleSagaHistory } ,
238- } ,
239- } ) ;
240-
241- //assert
242-
243- componentDriver . assert . thereAreTheFollowingSagaChangesInThisOrder ( [
244- {
245- expectedTime : startTimeD ,
246- } ,
247- {
248- expectedTime : startTimeC ,
249- } ,
250- {
251- expectedTime : startTimeB ,
252- } ,
253- {
254- expectedTime : startTimeA ,
255- } ,
256- ] ) ;
178+ componentDriver . assert . thereAreTheFollowingSagaChangesInThisOrder ( [ startTimeD , startTimeC , startTimeB , startTimeA ] ) ;
257179 } ) ;
258180 } ) ;
259181} ) ;
@@ -335,30 +257,29 @@ function rendercomponent({ initialState = {} }: { initialState?: { MessageStore?
335257 expect ( sagaGuid ) . toBeInTheDocument ( ) ;
336258 expect ( sagaGuid ) . toHaveTextContent ( guid ) ;
337259 } ,
338- thereAreTheFollowingSagaChangesInThisOrder : function ( sagaUpdates : { expectedTime : Date } [ ] ) : void {
260+ thereAreTheFollowingSagaChangesInThisOrder : function ( expectedDatesInOrder : Date [ ] ) : void {
339261 //Retrive the main parent component that contains the saga changes
340262 const sagaChangesContainer = screen . getByRole ( "table" , { name : / s a g a - s e q u e n c e - l i s t / i } ) ;
341263
342264 const sagaUpdatesElements = within ( sagaChangesContainer ) . queryAllByRole ( "row" ) ;
343265 //from within each sagaUpdatesElements get the values of an element with aria-label="time stamp"
344- //and check if the values are in the same order as the sagaUpdates array passed to this function
266+ //and check if the values are in the same order as the expectedDatesInOrder array passed to this function
345267 const sagaUpdatesTimestamps = sagaUpdatesElements . map ( ( item : HTMLElement ) => within ( item ) . getByLabelText ( "time stamp" ) ) ;
346268
347- //expect the number of found sagaUpdatesTimestamps to be the same as the number of sagaUpdates passed to this function
348- expect ( sagaUpdatesTimestamps ) . toHaveLength ( sagaUpdates . length ) ;
269+ //expect the number of found sagaUpdatesTimestamps to be the same as the number of expected dates passed to this function
270+ expect ( sagaUpdatesTimestamps ) . toHaveLength ( expectedDatesInOrder . length ) ;
349271
350272 const sagaUpdatesTimestampsValues = sagaUpdatesTimestamps . map ( ( item ) => item . innerHTML ) ;
351273
352- // Parse the rendered timestamp strings back to Date objects for comparison
353- const parsedDatesFromUI = sagaUpdatesTimestampsValues . map ( ( timestampString ) => {
354- // Parse the retrieved timestamp string back to a Date
355- return new Date ( timestampString ) ;
356- } ) ;
357-
358- const expectedDates = sagaUpdates . map ( ( item ) => item . expectedTime ) ;
274+ // Verify we have the same number of rendered timestamps as expected dates
275+ expect ( sagaUpdatesTimestampsValues ) . toHaveLength ( expectedDatesInOrder . length ) ;
359276
360- // Compare the dates directly
361- expect ( parsedDatesFromUI ) . toEqual ( expectedDates ) ;
277+ // For each rendered timestamp, verify it matches the expected date at that position
278+ // by formatting the expected date the same way and comparing strings
279+ expectedDatesInOrder . forEach ( ( expectedDate , index ) => {
280+ const expectedFormattedString = expectedDate . toLocaleString ( ) ;
281+ expect ( sagaUpdatesTimestampsValues [ index ] ) . toBe ( expectedFormattedString ) ;
282+ } ) ;
362283 } ,
363284 } ,
364285 } ;
0 commit comments