Rediseño Charts iPad, zoom en gráficas, eliminación de Focus Mode y fixes de rendimiento
Charts iPad (rediseño): - Fila de KPIs sobre el chart: Total Value, Period Return, CAGR, Volatility y Max Drawdown del rango activo (nuevo ChartsViewModel.portfolioMetrics, calculado sobre los TOTALES MENSUALES AGREGADOS — pasar snapshots multi-source crudos a calculateMetrics producía KPIs absurdos) - Sidebar (248pt) con tiles de chart type en grid 2 col agrupados por sección: Overview / Analyze / Risk / Forecast, con candado premium y accesibilidad - Selector de periodo como Picker segmentado nativo en la cabecera del chart (fuera del sidebar); título + descripción del chart visibles - Eliminado sheet de paywall duplicado del layout iPad Zoom (todas las series temporales): - Nuevo ChartZoom.swift: pinch + botones +/- y reset (HIG: el gesto nunca es el único camino), chartScrollableAxes + chartXVisibleDomain al hacer zoom - Integrado en Evolution, Contributions, Rolling 12M, Cashflow, Drawdown y Volatility Focus Mode eliminado (todo siempre disponible): - Fuera el toggle de Dashboard/Charts/Settings/Onboarding y los 6 @AppStorage - Todos los chart types siempre visibles; variantes completas en SourceDetail/SourceList - Home: Total Portfolio Value muestra SIEMPRE el cambio desde el último check-in - PeriodReturnsCard siempre visible Rendimiento y bugs (de la auditoría): - El cache de snapshots ya no se invalida al cambiar solo de chart type/rango/breakdown - calculateAnnualizedGrowth y el forecast a 12 meses ahora componen (la aproximación lineal sobreestimaba con historiales cortos) - Drawdown sin force unwrap; simulador: rama muerta reemplazada por preservación real de las asignaciones simuladas del usuario - UITest de captura de Charts con manejo del alert de notificaciones 12 strings nuevas localizadas en los 7 idiomas. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015qUZrBusG82T37R7PeokqJ
This commit is contained in:
@@ -119,6 +119,44 @@ final class PortfolioJournalUITests: XCTestCase {
|
||||
|
||||
// MARK: - App Store Screenshot Capture
|
||||
|
||||
/// Captures the redesigned iPad Charts screen (sidebar tiles + KPI header).
|
||||
/// Works on both iPad (sidebar buttons) and iPhone (tab bar).
|
||||
func testCaptureChartsScreen() throws {
|
||||
let capture = XCUIApplication()
|
||||
capture.launchArguments = ["--screenshots"]
|
||||
capture.launch()
|
||||
|
||||
// Wait for main UI (tab bar on iPhone, sidebar on iPad)
|
||||
Thread.sleep(forTimeInterval: 4.0)
|
||||
|
||||
// Dismiss the notification-permission system alert if it appears
|
||||
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
|
||||
let denyButton = springboard.alerts.buttons["Don't Allow"]
|
||||
if denyButton.waitForExistence(timeout: 3) {
|
||||
denyButton.tap()
|
||||
Thread.sleep(forTimeInterval: 1.0)
|
||||
}
|
||||
|
||||
// Try tab bar first (iPhone), then any button labeled Charts (iPad sidebar)
|
||||
let tabBar = capture.tabBars.firstMatch
|
||||
if tabBar.exists && tabBar.buttons["Charts"].exists {
|
||||
tabBar.buttons["Charts"].tap()
|
||||
} else {
|
||||
let chartsButton = capture.buttons["Charts"].firstMatch
|
||||
if chartsButton.waitForExistence(timeout: 5) {
|
||||
chartsButton.tap()
|
||||
} else {
|
||||
capture.staticTexts["Charts"].firstMatch.tap()
|
||||
}
|
||||
}
|
||||
Thread.sleep(forTimeInterval: 3.0)
|
||||
|
||||
let shot = XCTAttachment(screenshot: capture.screenshot())
|
||||
shot.name = "Charts_Redesign"
|
||||
shot.lifetime = .keepAlways
|
||||
add(shot)
|
||||
}
|
||||
|
||||
/// Captures full-screen screenshots of the main tabs with demo data for App Store
|
||||
/// marketing. Launches the app in `--screenshots` mode (onboarding/lock skipped,
|
||||
/// SampleDataService seeded). Language can be driven via the SCREENSHOT_LANG env var
|
||||
|
||||
Reference in New Issue
Block a user