@@ -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 : { expectedRenderedLocalTime : string } [ ] ) : 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,23 +134,33 @@ 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
137144 //so that the reader of this test can see the preconditions at play
138145 //and understand the test better without having to jump around
139- sampleSagaHistory . changes [ 0 ] . start_time = new Date ( "2025-03-28T03:04:08.3819211Z" ) ; // A
140- sampleSagaHistory . changes [ 0 ] . finish_time = new Date ( "2025-03-28T03:04:08.3836Z" ) ; // A1
141- sampleSagaHistory . changes [ 1 ] . start_time = new Date ( "2025-03-28T03:04:07.5416262Z" ) ; // B
142- sampleSagaHistory . changes [ 1 ] . finish_time = new Date ( "2025-03-28T03:04:07.5509712Z" ) ; //B1
143- sampleSagaHistory . changes [ 2 ] . start_time = new Date ( "2025-03-28T03:04:06.3088353Z" ) ; //C
144- sampleSagaHistory . changes [ 2 ] . finish_time = new Date ( "2025-03-28T03:04:06.3218175Z" ) ; //C1
145- sampleSagaHistory . changes [ 3 ] . start_time = new Date ( "2025-03-28T03:04:05.3332078Z" ) ; //D
146- sampleSagaHistory . changes [ 3 ] . finish_time = new Date ( "2025-03-28T03:04:05.3799483Z" ) ; //D1
146+
147+ const startTimeA = new Date ( "2025-03-28T03:04:08.000Z" ) ;
148+ const finishTimeA1 = new Date ( "2025-03-28T03:04:08.000Z" ) ;
149+ const startTimeB = new Date ( "2025-03-28T03:04:07.000Z" ) ;
150+ const finishTimeB1 = new Date ( "2025-03-28T03:04:07.000Z" ) ;
151+ const startTimeC = new Date ( "2025-03-28T03:04:06.000Z" ) ;
152+ const finishTimeC1 = new Date ( "2025-03-28T03:04:06.000Z" ) ;
153+ const startTimeD = new Date ( "2025-03-28T03:04:05.000Z" ) ;
154+ const finishTimeD1 = new Date ( "2025-03-28T03:04:05.000Z" ) ;
155+
156+ sampleSagaHistory . changes [ 0 ] . start_time = startTimeA ;
157+ sampleSagaHistory . changes [ 0 ] . finish_time = finishTimeA1 ;
158+ sampleSagaHistory . changes [ 1 ] . start_time = startTimeB ;
159+ sampleSagaHistory . changes [ 1 ] . finish_time = finishTimeB1 ;
160+ sampleSagaHistory . changes [ 2 ] . start_time = startTimeC ;
161+ sampleSagaHistory . changes [ 2 ] . finish_time = finishTimeC1 ;
162+ sampleSagaHistory . changes [ 3 ] . start_time = startTimeD ;
163+ sampleSagaHistory . changes [ 3 ] . finish_time = finishTimeD1 ;
147164 sampleSagaHistory . changes [ 3 ] . status = "new" ;
148165
149166 //B(1), C(2), A(0), D(3)
@@ -158,84 +175,7 @@ describe("Feature: 3 Visual Representation of Saga Timeline", () => {
158175 } ) ;
159176
160177 //assert
161-
162- componentDriver . assert . thereAreTheFollowingSagaChangesInThisOrder ( [
163- {
164- expectedRenderedLocalTime : "3/28/2025 3:04:05 AM" ,
165- } ,
166- {
167- expectedRenderedLocalTime : "3/28/2025 3:04:06 AM" ,
168- } ,
169- {
170- expectedRenderedLocalTime : "3/28/2025 3:04:07 AM" ,
171- } ,
172- {
173- expectedRenderedLocalTime : "3/28/2025 3:04:08 AM" ,
174- } ,
175- ] ) ;
176- } ) ;
177- } ) ;
178- describe ( "Rule: 3.3 Display a chronological timeline of saga events in PST." , ( ) => {
179- test ( "EXAMPLE: Rendering a Saga with 4 changes" , ( ) => {
180- // 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.
181- //TODO: "Incoming messages are displayed on the left, and outgoing messages are displayed on the right." in another test?
182-
183- //arragement
184- //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
185- const messageStore = { } as MessageStore ;
186- messageStore . state = { } as MessageStore [ "state" ] ;
187- messageStore . state . data = { } as MessageStore [ "state" ] [ "data" ] ;
188- messageStore . state . data . invoked_saga = {
189- has_saga : true ,
190- saga_id : "123" ,
191- saga_type : "ServiceControl.SmokeTest.AuditingSaga" ,
192- } ;
193-
194- // Set the environment to a fixed timezone
195- // JSDOM, used by Vitest, defaults to PST timezone
196- // To ensure consistency, explicitly set the timezone to PST
197- // This ensures that the rendered local time of the saga changes
198- // will always be interpreted and displayed in "America/Los_Angeles"
199- process . env . TZ = "America/Los_Angeles" ;
200-
201- //access each of the saga changes and update its start time and finish time to the same values being read from the variable declaration,
202- // but set them again explicitly here
203- //so that the reader of this test can see the preconditions at play
204- //and understand the test better without having to jump around
205- sampleSagaHistory . changes [ 0 ] . start_time = new Date ( "2025-03-28T03:04:08.3819211Z" ) ; // A
206- sampleSagaHistory . changes [ 0 ] . finish_time = new Date ( "2025-03-28T03:04:08.3836Z" ) ; // A1
207- sampleSagaHistory . changes [ 1 ] . start_time = new Date ( "2025-03-28T03:04:07.5416262Z" ) ; // B
208- sampleSagaHistory . changes [ 1 ] . finish_time = new Date ( "2025-03-28T03:04:07.5509712Z" ) ; //B1
209- sampleSagaHistory . changes [ 2 ] . start_time = new Date ( "2025-03-28T03:04:06.3088353Z" ) ; //C
210- sampleSagaHistory . changes [ 2 ] . finish_time = new Date ( "2025-03-28T03:04:06.3218175Z" ) ; //C1
211- sampleSagaHistory . changes [ 3 ] . start_time = new Date ( "2025-03-28T03:04:05.3332078Z" ) ; //D
212- sampleSagaHistory . changes [ 3 ] . finish_time = new Date ( "2025-03-28T03:04:05.3799483Z" ) ; //D1
213- sampleSagaHistory . changes [ 3 ] . status = "new" ;
214-
215- // Set up the store with sample saga history
216- const componentDriver = rendercomponent ( {
217- initialState : {
218- MessageStore : messageStore ,
219- SagaDiagramStore : { sagaHistory : sampleSagaHistory } ,
220- } ,
221- } ) ;
222-
223- //assert
224-
225- componentDriver . assert . thereAreTheFollowingSagaChangesInThisOrder ( [
226- {
227- expectedRenderedLocalTime : "3/27/2025 8:04:05 PM" ,
228- } ,
229- {
230- expectedRenderedLocalTime : "3/27/2025 8:04:06 PM" ,
231- } ,
232- {
233- expectedRenderedLocalTime : "3/27/2025 8:04:07 PM" ,
234- } ,
235- {
236- expectedRenderedLocalTime : "3/27/2025 8:04:08 PM" ,
237- } ,
238- ] ) ;
178+ componentDriver . assert . thereAreTheFollowingSagaChangesInThisOrder ( [ startTimeD , startTimeC , startTimeB , startTimeA ] ) ;
239179 } ) ;
240180 } ) ;
241181} ) ;
@@ -317,21 +257,29 @@ function rendercomponent({ initialState = {} }: { initialState?: { MessageStore?
317257 expect ( sagaGuid ) . toBeInTheDocument ( ) ;
318258 expect ( sagaGuid ) . toHaveTextContent ( guid ) ;
319259 } ,
320- thereAreTheFollowingSagaChangesInThisOrder : function ( sagaUpdates : { expectedRenderedLocalTime : string } [ ] ) : void {
260+ thereAreTheFollowingSagaChangesInThisOrder : function ( expectedDatesInOrder : Date [ ] ) : void {
321261 //Retrive the main parent component that contains the saga changes
322262 const sagaChangesContainer = screen . getByRole ( "table" , { name : / s a g a - s e q u e n c e - l i s t / i } ) ;
323263
324264 const sagaUpdatesElements = within ( sagaChangesContainer ) . queryAllByRole ( "row" ) ;
325- //from within each sagaUpdatesElemtns get the values of an element with aria-label="time stamp"
326- //and check if the values are in the same order as the sagaUpdates array passed to this function
265+ //from within each sagaUpdatesElements get the values of an element with aria-label="time stamp"
266+ //and check if the values are in the same order as the expectedDatesInOrder array passed to this function
327267 const sagaUpdatesTimestamps = sagaUpdatesElements . map ( ( item : HTMLElement ) => within ( item ) . getByLabelText ( "time stamp" ) ) ;
328268
329- //expect the number of found sagaUpdatesTimestamps to be the same as the number of sagaUpdates passed to this function
330- 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 ) ;
331271
332272 const sagaUpdatesTimestampsValues = sagaUpdatesTimestamps . map ( ( item ) => item . innerHTML ) ;
333- // //check if the values are in the same order as the sagaUpdates array passed to this function
334- expect ( sagaUpdatesTimestampsValues ) . toEqual ( sagaUpdates . map ( ( item ) => item . expectedRenderedLocalTime ) ) ;
273+
274+ // Verify we have the same number of rendered timestamps as expected dates
275+ expect ( sagaUpdatesTimestampsValues ) . toHaveLength ( expectedDatesInOrder . length ) ;
276+
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+ } ) ;
335283 } ,
336284 } ,
337285 } ;
0 commit comments