Files
orca/src/shared/feature-tips.test.ts
T
Brennan Benson 820277c207 Show pre-upgrade Experimental Chat UI users a one-time native chat upgrade tip (#26710)
* feat(native-chat): one-time upgrade tip for pre-upgrade Experimental Chat UI users

Show the new native chat upgrade tip through the normal startup feature-tip
flow, only to profiles whose saved Experimental Chat UI setting was on before
this release. Main records that audience once, from the profile as saved by the
previous build, and never re-derives it from the live setting, so later
opt-ins, new installs and the future graduation stay excluded.

* fix(native-chat): keep the upgrade tip readable and dismissed

Focus Got it without scrolling and tighten the ja/es/fr copy so the title is
visible on open. Show the tip exactly like other startup tips (no resume-dialog
wait), keep the illustration's upward menu unclipped, and merge seen tip ids
on save so a stale client cannot bring a dismissed tip back.

* fix(native-chat): say "between chat and CLI" in French and pin the audience basis in tests
2026-10-08 19:30:43 -07:00

147 lines
4.5 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import {
FEATURE_TIPS,
getCompletedFeatureTipIds,
getOrderedUnseenFeatureTips,
normalizeFeatureTipIds,
type FeatureTipId
} from './feature-tips'
describe('feature tips', () => {
it('orders new unseen tips before older unseen tips', () => {
const tips = getOrderedUnseenFeatureTips({ seenTipIds: new Set<FeatureTipId>() })
expect(tips.map((tip) => tip.id)).toEqual([
'native-chat-upgrade',
'agent-session-search',
'orca-cli',
'cmd-j-palette',
'voice-dictation'
])
})
it('treats the native chat upgrade tip as done for every profile outside its audience', () => {
const base = {
cliInstalled: true,
voiceDictationEnabled: true,
sessionSearchTipCompleted: true
}
expect(
getCompletedFeatureTipIds({ ...base, inNativeChatUpgradeTipAudience: false }).has(
'native-chat-upgrade'
)
).toBe(true)
expect(
getCompletedFeatureTipIds({ ...base, inNativeChatUpgradeTipAudience: true }).has(
'native-chat-upgrade'
)
).toBe(false)
})
it('skips tips the user has already seen', () => {
const tips = getOrderedUnseenFeatureTips({
seenTipIds: new Set<FeatureTipId>([
'native-chat-upgrade',
'voice-dictation',
'orca-cli',
'cmd-j-palette',
'agent-session-search'
])
})
expect(tips.map((tip) => tip.id)).toEqual([])
})
it('skips tips for features the user has already completed', () => {
const tips = getOrderedUnseenFeatureTips({
// cmd-j is a seen-based tip with no feature completion, so mark it seen here.
seenTipIds: new Set<FeatureTipId>(['cmd-j-palette']),
completedTipIds: getCompletedFeatureTipIds({
cliInstalled: true,
voiceDictationEnabled: true,
sessionSearchTipCompleted: true,
inNativeChatUpgradeTipAudience: false
})
})
expect(tips.map((tip) => tip.id)).toEqual([])
})
it('skips the CLI tip when the CLI is already installed', () => {
const tips = getOrderedUnseenFeatureTips({
seenTipIds: new Set<FeatureTipId>(['voice-dictation', 'cmd-j-palette']),
completedTipIds: getCompletedFeatureTipIds({
cliInstalled: true,
voiceDictationEnabled: false,
sessionSearchTipCompleted: true,
inNativeChatUpgradeTipAudience: false
})
})
expect(tips.map((tip) => tip.id)).toEqual([])
})
it('skips tips for features the user has already interacted with', () => {
const tips = getOrderedUnseenFeatureTips({
seenTipIds: new Set<FeatureTipId>(),
completedTipIds: getCompletedFeatureTipIds({
cliInstalled: false,
voiceDictationEnabled: false,
sessionSearchTipCompleted: true,
inNativeChatUpgradeTipAudience: false,
featureInteractions: {
'voice-dictation': { firstInteractedAt: 100, interactionCount: 1 }
}
})
})
expect(tips.map((tip) => tip.id)).toEqual(['orca-cli', 'cmd-j-palette'])
})
it('normalizes persisted tip ids', () => {
expect(
normalizeFeatureTipIds([
'feature-tour',
'orca-cli',
'bogus',
'cmd-j-palette',
'voice-dictation'
])
).toEqual(['orca-cli', 'cmd-j-palette', 'voice-dictation'])
})
it('describes the command palette tip as a passive acknowledgement', () => {
const paletteTip = FEATURE_TIPS.find((tip) => tip.id === 'cmd-j-palette')
expect(paletteTip).toMatchObject({
action: 'learn-cmd-j-palette',
priority: 'new',
eyebrow: 'Tip',
ctaLabel: 'Got it'
})
expect(paletteTip?.description).toContain('worktrees')
expect(paletteTip?.description).toContain('spin up a new worktree')
})
it('describes the CLI tip as an install action with concrete workflows', () => {
const cliTip = FEATURE_TIPS.find((tip) => tip.id === 'orca-cli')
expect(cliTip).toMatchObject({
action: 'setup-cli',
title: 'Let agents drive Orca with the Orca CLI',
ctaLabel: 'Install CLI & Skills'
})
expect(cliTip?.description).toContain('coordinate child worktrees')
expect(cliTip?.description).toContain('communicate between worktrees')
})
it('does not label the voice dictation tip as new', () => {
const voiceTip = FEATURE_TIPS.find((tip) => tip.id === 'voice-dictation')
expect(voiceTip?.eyebrow).toBe('Tip')
expect(voiceTip?.priority).toBe('unseen')
expect(voiceTip?.title).toBe('Dictate into any pane')
expect(voiceTip?.ctaLabel).toBe('Set up voice dictation')
})
})