@@ -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 : { expectedRenderedLocalTime : string } [ ] ) : 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,23 +134,33 @@ 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
137
144
//so that the reader of this test can see the preconditions at play
138
145
//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 ;
147
164
sampleSagaHistory . changes [ 3 ] . status = "new" ;
148
165
149
166
//B(1), C(2), A(0), D(3)
@@ -158,84 +175,7 @@ describe("Feature: 3 Visual Representation of Saga Timeline", () => {
158
175
} ) ;
159
176
160
177
//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 ] ) ;
239
179
} ) ;
240
180
} ) ;
241
181
} ) ;
@@ -317,21 +257,29 @@ function rendercomponent({ initialState = {} }: { initialState?: { MessageStore?
317
257
expect ( sagaGuid ) . toBeInTheDocument ( ) ;
318
258
expect ( sagaGuid ) . toHaveTextContent ( guid ) ;
319
259
} ,
320
- thereAreTheFollowingSagaChangesInThisOrder : function ( sagaUpdates : { expectedRenderedLocalTime : string } [ ] ) : void {
260
+ thereAreTheFollowingSagaChangesInThisOrder : function ( expectedDatesInOrder : Date [ ] ) : void {
321
261
//Retrive the main parent component that contains the saga changes
322
262
const sagaChangesContainer = screen . getByRole ( "table" , { name : / s a g a - s e q u e n c e - l i s t / i } ) ;
323
263
324
264
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
327
267
const sagaUpdatesTimestamps = sagaUpdatesElements . map ( ( item : HTMLElement ) => within ( item ) . getByLabelText ( "time stamp" ) ) ;
328
268
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 ) ;
331
271
332
272
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
+ } ) ;
335
283
} ,
336
284
} ,
337
285
} ;
0 commit comments