Skip to content
Merged
21 changes: 21 additions & 0 deletions packages/ui/src/__tests__/chat-turn-answer-identity.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,27 @@ test('uses human conversation context instead of raw ids in action names', async
);
});

test('keeps Astryx auto formatting live for user-message timestamps', async (context) => {
const now = Date.UTC(2026, 7, 27, 12);
context.mock.timers.enable({ apis: ['Date', 'setInterval'], now });
const { container, root } = domRoot();
const twoHoursAgo = now - 2 * 60 * 60 * 1_000;
const turn = {
...turnWith([{ ...ANSWER, live: false }]),
user: { id: 'ask', role: 'user' as const, text: 'ask', ts: twoHoursAgo },
};

await renderTurn(root, turn);

const timestamp = container.querySelector('.maka-message-time-inline time');
assert.ok(timestamp, 'Astryx Timestamp renders the semantic time element');
assert.match(timestamp.textContent ?? '', /2 hours ago/);
assert.equal(timestamp.getAttribute('tabindex'), '0', 'the absolute-time hover card is keyboard reachable');

await act(() => context.mock.timers.tick(60 * 60 * 1_000));
assert.match(timestamp.textContent ?? '', /3 hours ago/);
});

/**
* The live handoff announces itself exactly once, when the answer enters its
* settled phase. A bubble replayed from history mounts already past the
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/chat-turn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ const UserMessageBody = memo(function UserMessageBody(props: {
/* `value` takes ms directly: Timestamp's own parseValue reads
anything past 1e12 as milliseconds (2001-09-09 onward), and a
chat message never predates that. */
(<Timestamp className="maka-message-time-inline" value={props.ts} format="time" />)
(<Timestamp className="maka-message-time-inline" value={props.ts} format="auto" isLive />)
) : undefined
}
footer={
Expand Down