Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions docs/UX-BENCHMARKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ Scheduled(有日期的)。

- ✅ macOS 已落地:⌘/⇧ 多选 + 批量完成/排期/移动/删除,删除走单条撤销横幅
(PRODUCT-SPEC §5b 已收录批量语义)。
- ✅ Windows 列表选择基础:WinUI Extended 模式支持 Ctrl/Shift
多选、方向键与范围选择;Enter 打开当前选中任务的编辑对话框,Esc
清除选择。按任务 ID 在列表刷新后恢复选择(普通列表与搜索结果)。
- ✅ Windows 列表选择与行内详情:WinUI Extended 模式支持 Ctrl/Shift
多选、方向键与范围选择;Enter、双击或 ⓘ 在当前行展开标题、备注、日期与时间,
不再调用 PromptAsync。Enter 保存、Esc 取消;切换行时保存。按任务 ID 在列表刷新后
恢复选择与编辑草稿(普通列表与搜索结果)。
- ✅ Windows 批量操作(分阶段):选择多条任务时显示共享操作栏;
支持一次批量标记完成、批量移动到目标列表;使用稳定任务 ID,列表刷新
与搜索不会把操作错误应用到其他任务。打包验收覆盖两条任务批量完成。
Expand All @@ -91,7 +92,7 @@ Scheduled(有日期的)。
- ✅ Linux:基于 GTK 原生多选(#33)增加可见的批量完成和批量移动操作栏,
同时适用于当前列表和全局搜索。刷新时按任务 ID 保留选择。
- ✅ Windows 单条/批量删除采用 6 秒延后提交:先隐藏选中任务,期间撤销可直接恢复原任务 ID 与元数据,超时才发送后端删除 RPC;失败时恢复任务。
- 🔜 **尚未完成**:Windows 行内详情展开;Linux 批量删除及撤销;以及三平台按真实快捷键进行实机回归。
- 🔜 **尚未完成**:三平台按真实快捷键进行实机回归。

### 2.5 Quick Find

Expand Down
77 changes: 75 additions & 2 deletions scripts/e2e/e2e-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ last-update-check = $epoch
"@ | Set-Content -LiteralPath (Join-Path $tasklyHome 'config.ini') -Encoding utf8

function Wait-Until {
param([string]$Description, [scriptblock]$Probe, [int]$TimeoutSeconds = 30)
param([string]$Description, [scriptblock]$Probe, [int]$TimeoutSeconds = 60)
$deadline = [DateTime]::UtcNow.AddSeconds($TimeoutSeconds)
while ([DateTime]::UtcNow -lt $deadline) {
$value = & $Probe
Expand Down Expand Up @@ -185,6 +185,78 @@ try {
throw 'Windows task list must support Ctrl/Shift multi-selection'
}

# Task details must expand in place. A modal PromptAsync text box is not
# acceptable here because it cannot edit notes/date/time and breaks the
# Reminders-style Return/Esc flow.
$taskInfo = Wait-Until 'inline task details button' {
Find-ById $window 'task-info-2'
}
$taskInfo.GetCurrentPattern(
[System.Windows.Automation.InvokePattern]::Pattern).Invoke()
$inlineTitle = Wait-Until 'inline task title editor' {
Find-ById $window 'inline-task-title-2'
}
if ($null -ne (Find-ById $window 'prompt-input')) {
throw 'task details opened the legacy PromptAsync dialog'
}
$inlineNotes = Wait-Until 'inline task notes editor' {
Find-ById $window 'inline-task-notes-2'
}
$inlineDate = Wait-Until 'inline task date editor' {
Find-ById $window 'inline-task-date-2'
}
$inlineTime = Wait-Until 'inline task time editor' {
Find-ById $window 'inline-task-time-2'
}
$editedPlainTask = 'Life-only task edited inline'
$editedNotes = 'Inline notes survive a changed-event refresh'
$inlineTitle.GetCurrentPattern(
[System.Windows.Automation.ValuePattern]::Pattern).SetValue($editedPlainTask)
$inlineNotes.GetCurrentPattern(
[System.Windows.Automation.ValuePattern]::Pattern).SetValue($editedNotes)
$inlineDate.GetCurrentPattern(
[System.Windows.Automation.ValuePattern]::Pattern).SetValue('2099-12-31')
$inlineTime.GetCurrentPattern(
[System.Windows.Automation.ValuePattern]::Pattern).SetValue('10:30')
$inlineTitle.SetFocus()
[System.Windows.Forms.SendKeys]::SendWait('{ENTER}')
[void](Wait-Until 'inline task edit persisted' {
if ($null -ne (Find-ByName $window $editedPlainTask) -and
$null -ne (Find-ById $window 'task-notes-2')) { return $true }
return $false
})
$plainTask = $editedPlainTask

# Reopen after the backend changed-event rebuild and verify every field
# was read back from persistence, not merely retained in the visual tree.
$taskInfo = Wait-Until 'reopen inline task details' {
Find-ById $window 'task-info-2'
}
$taskInfo.GetCurrentPattern(
[System.Windows.Automation.InvokePattern]::Pattern).Invoke()
$persistedNotes = Wait-Until 'persisted inline notes' {
Find-ById $window 'inline-task-notes-2'
}
$persistedDate = Wait-Until 'persisted inline date' {
Find-ById $window 'inline-task-date-2'
}
$persistedTime = Wait-Until 'persisted inline time' {
Find-ById $window 'inline-task-time-2'
}
if ($persistedNotes.GetCurrentPattern(
[System.Windows.Automation.ValuePattern]::Pattern).Current.Value -ne $editedNotes -or
$persistedDate.GetCurrentPattern(
[System.Windows.Automation.ValuePattern]::Pattern).Current.Value -ne '2099-12-31' -or
$persistedTime.GetCurrentPattern(
[System.Windows.Automation.ValuePattern]::Pattern).Current.Value -ne '10:30') {
throw 'inline task details were not persisted across the backend refresh'
}
$taskInfo = Wait-Until 'collapse inline task details' {
Find-ById $window 'task-info-2'
}
$taskInfo.GetCurrentPattern(
[System.Windows.Automation.InvokePattern]::Pattern).Invoke()

Select-TaskList 1 '工作'
[void](Wait-Until '工作 view selected' {
if ($paneTitle.Current.Name -eq '工作') { return $true }
Expand Down Expand Up @@ -324,7 +396,7 @@ try {
[ordered]@{
platform = 'windows'
artifact = $executable.FullName
actions = @('set:quick-add', 'invoke:quick-add-submit', 'toggle:task-complete-1', 'create-list:生活', 'select-list:2', 'enter:quick-add', 'select-list:1', 'select-list:2')
actions = @('set:quick-add', 'invoke:quick-add-submit', 'toggle:task-complete-1', 'create-list:生活', 'select-list:2', 'enter:quick-add', 'inline:edit-task-2', 'select-list:1', 'select-list:2')
assertions = @(
'packaged WinUI window activated',
'stable UI Automation identifiers exposed',
Expand All @@ -333,6 +405,7 @@ try {
'new task submitted by Enter is owned by 生活, not 工作',
'task checkbox and plain-text title are vertically aligned',
'Windows task list exposes native multiple selection',
'task details expand inline without PromptAsync and persist title, notes, date, and time',
'view switches preserve task list ownership',
'global search shows the real owning list for every task',
'Ctrl/Shift multi-selection completes two tasks in one command',
Expand Down
Loading
Loading