@@ -14,7 +14,7 @@ interface componentDSL {
14
14
15
15
//Defines a domain-specific language (DSL) for checking assertions against the system under test (sut)
16
16
interface componentDSLAssertions {
17
- thereAreTheFollowingSagaChangesInThisOrder ( sagaUpdates : { expectedTime : Date } [ ] ) : void ;
17
+ thereAreTheFollowingSagaChangesInThisOrder ( expectedDatesInOrder : Date [ ] ) : void ;
18
18
displayedSagaGuidIs ( sagaId : string ) : void ;
19
19
displayedSagaNameIs ( humanizedSagaName : string ) : void ;
20
20
linkIsShown ( arg0 : { withText : string ; withHref : string } ) : void ;
@@ -109,8 +109,15 @@ describe("Feature: 3 Visual Representation of Saga Timeline", () => {
109
109
} ) ;
110
110
} ) ;
111
111
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 } ) => {
114
121
// 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.
115
122
//TODO: "Incoming messages are displayed on the left, and outgoing messages are displayed on the right." in another test?
116
123
@@ -127,10 +134,10 @@ describe("Feature: 3 Visual Representation of Saga Timeline", () => {
127
134
128
135
// Set the environment to a fixed timezone
129
136
// 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
131
138
// 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 ;
134
141
135
142
//access each of the saga changes and update its start time and finish time to the same values being read from the variable declaration,
136
143
// but set them again explicitly here
@@ -168,92 +175,7 @@ describe("Feature: 3 Visual Representation of Saga Timeline", () => {
168
175
} ) ;
169
176
170
177
//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 ] ) ;
257
179
} ) ;
258
180
} ) ;
259
181
} ) ;
@@ -335,30 +257,29 @@ function rendercomponent({ initialState = {} }: { initialState?: { MessageStore?
335
257
expect ( sagaGuid ) . toBeInTheDocument ( ) ;
336
258
expect ( sagaGuid ) . toHaveTextContent ( guid ) ;
337
259
} ,
338
- thereAreTheFollowingSagaChangesInThisOrder : function ( sagaUpdates : { expectedTime : Date } [ ] ) : void {
260
+ thereAreTheFollowingSagaChangesInThisOrder : function ( expectedDatesInOrder : Date [ ] ) : void {
339
261
//Retrive the main parent component that contains the saga changes
340
262
const sagaChangesContainer = screen . getByRole ( "table" , { name : / s a g a - s e q u e n c e - l i s t / i } ) ;
341
263
342
264
const sagaUpdatesElements = within ( sagaChangesContainer ) . queryAllByRole ( "row" ) ;
343
265
//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
345
267
const sagaUpdatesTimestamps = sagaUpdatesElements . map ( ( item : HTMLElement ) => within ( item ) . getByLabelText ( "time stamp" ) ) ;
346
268
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 ) ;
349
271
350
272
const sagaUpdatesTimestampsValues = sagaUpdatesTimestamps . map ( ( item ) => item . innerHTML ) ;
351
273
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 ) ;
359
276
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
+ } ) ;
362
283
} ,
363
284
} ,
364
285
} ;
0 commit comments