Commit graph

2952 commits

Author SHA1 Message Date
lin onetwo
a9f192b642
Potential fix for pull request finding 'CodeQL / Shell command built from environment values'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-05-06 00:06:40 +08:00
linonetwo
5c536b217f fix(e2e): handle calibration run failures gracefully
Calibration preflight runs multiple smoke test iterations. If one
run fails (e.g. a scenario times out), skip its data and use
results from successful runs. Only fail if ALL runs fail.
2026-05-05 22:29:31 +08:00
linonetwo
7f08a8e3f0 fix(e2e): use generous 120s ceiling for all cucumber and internal timeouts
Cucumber step timeout = 120s (safety net, rarely reached).
Playwright element timeout = 10s (fast fail for missing elements).
Playwright system operations = 120s (process launch, window management).
Log marker wait = 120s (generous ceiling with internal retries).

Quick failures come from PLAYWRIGHT_TIMEOUT (10s), not cucumber.
System operations have room to complete without timeouts.
2026-05-05 22:19:53 +08:00
linonetwo
3d67516f61 fix(e2e): use generous 120s timeout for all Playwright system operations
electron.launch, firstWindow, waitForLoadState are system-level
operations (process creation, window management), not test assertions.
They need generous timeouts independent of measured step time.
Cucumber step timeout still catches truly hung test steps.
2026-05-05 19:12:04 +08:00
linonetwo
efc41728e9 fix(e2e): use generous 120s timeout for electron process launch
electron.launch() is a system-level process creation, not a test step.
It needs a generous timeout independent of measured step time. The
cucumber step timeout (measured from calibration) handles step-level
hangs, but the Playwright-level launch needs room for process startup.
2026-05-05 18:50:11 +08:00
linonetwo
15924886d7 fix(e2e): increase calibration runs to 4 for better launch sampling
6 launch samples (2 runs × 3 scenarios) missed 25% of slow launches.
12 samples (4 runs × 3 scenarios) should capture the 90th+ percentile.
2026-05-05 18:26:49 +08:00
linonetwo
dd5eec83c1 fix(e2e): add 3rd smoke scenario for more launch samples
All 16 failures were app launch timing out at 5.5s. Two scenarios × 2 runs
= 4 launch samples missed the 25%+ of launches that exceed 5.5s. Add a
minimal 3rd scenario (launch + page load check) to capture 6 samples
total and better cover the launch time distribution.
2026-05-05 17:36:03 +08:00
linonetwo
1d891823f8 refactor(e2e): per-type measurement — zero hardcoded timeouts
Calibration now classifies steps by type and stores per-type max durations:
- stepMs: all steps → CUCUMBER_GLOBAL_TIMEOUT
- launchMs: launch/browser-view steps → HEAVY_PLAYWRIGHT_TIMEOUT
- waitMs: wait/log/SSE/watch-fs steps → LOG_MARKER_WAIT_TIMEOUT

Every internal timeout now comes from measurement. Removed all hardcoded
subtractions (500, 4000, 5000 from LOG_MARKER_WAIT_TIMEOUT).
2026-05-05 17:07:35 +08:00
linonetwo
3979f96a92 fix(e2e): reduce log marker subtraction from 5000 to 500ms
With measured step timeouts (5.5s), the old formula gave LOG_MARKER_WAIT
= max(5000, 5500-5000) = 5000ms. Markers appearing at 5.2s would fail
the internal wait before the cucumber step timeout. Reduce buffer to 500ms
so internal timeouts stay close to measured worst-case step duration.
2026-05-05 16:06:08 +08:00
linonetwo
c6f71faaeb fix(e2e): split smoke test into 2 scenarios for loaded-state calibration
Scenario 1: launch app, enable watch, create 3 probe files (accumulates state)
Scenario 2: fresh launch on loaded system, restart wiki, measure watch-fs re-index
Both tagged @smoke so preflight runs both. Max step from scenario 2's
restart+watch-fs step captures watcher performance under load.
2026-05-05 13:40:40 +08:00
linonetwo
c8cc473850 fix(e2e): create 3 probe files before restart for loaded watcher measurement
Watcher re-index time scales with accumulated file state. Three file
additions before restart simulate the loaded state that causes 10-20×
slowdown in the full test suite vs. fresh calibration.
2026-05-05 13:09:02 +08:00
linonetwo
b98fb5d5b1 fix(e2e): add wiki restart to smoke test for watcher re-index measurement
The real bottleneck in the main test is NOT first-time watcher init
but watcher re-initialization after wiki restart (re-indexing files).
Add restart + watch-fs wait AFTER file operations to measure this.
2026-05-05 12:46:12 +08:00
linonetwo
e0af582103 fix(e2e): more file cycles in smoke test for sustained-load measurement
Single create/modify/delete only captures first-launch watcher latency
(6.4s), but main test watcher degrades 3-10× under multi-scenario load.
Add second file cycle to measure performance after sustained watcher use.
2026-05-05 00:50:59 +08:00
linonetwo
fb0a2711f7 fix(e2e): add real file operations to smoke test for calibration
The smoke test's heaviest step was 2.6s ('wait for SSE and watch-fs')
— but the main test's same step takes 10-40s under multi-scenario load.
Add create/modify/delete file + watch-fs detection to the calibration
scenario so maxStepMs reflects real worst-case watch-fs latency.
2026-05-05 00:25:00 +08:00
linonetwo
566a2ea92e refactor(e2e): all timeouts derived from measurement, zero hardcoded values
Calibration now extracts actual max individual step duration from
cucumber JSON output — no multipliers, REFERENCE, caps, or floors.
The measured worst-case step IS the timeout.

- calibration.ts: getMeasuredStepTimeoutMs() returns raw maxStepMs
- preflight: cucumber --format json → parse nanosecond durations
- timeouts.ts: CUCUMBER_GLOBAL_TIMEOUT = measured max step
- calibration mode: 1h timeout, purely for measurement to finish
- No REFERENCE_CALIBRATION_MS, no CALIBRATION_PREFLIGHT_MULTIPLIER
- No BASE_STEP_TIMEOUT_MS, no multipliers
- Missing calibration → throws immediately

Also fix CI deprecations:
- github/codeql-action/*@v3 → v4
- actions/upload-artifact@v4 → v5 (test.yml + release.yml)
2026-05-05 00:06:58 +08:00
linonetwo
173c6d6fba fix(e2e): increase BASE_STEP_TIMEOUT_MS to 80s for heavy op stability
At 1.0× (reference CI): 80s/step
At 1.24× (current CI): ~99s/step

Light Playwright timeouts (10s) are working correctly - all failures
were cucumber step timeouts (74s), not element-finding timeouts.
2026-05-04 23:28:04 +08:00
linonetwo
40f8b97a59 fix(e2e): lower REFERENCE_CALIBRATION_MS to 18000 for stability margin
REFERENCE=20000 gave multiplier < 1.0 on fast CI (0.97× → 58s timeout)
causing 7 scenario timeouts. REFERENCE=18000 (below min observed 19.4s)
ensures multiplier ≥ 1.0 (1.08× → 65s timeout on typical CI).

Light Playwright timeouts (10s) are working correctly - all failures
were cucumber step timeouts, not element-finding timeouts.
2026-05-04 22:53:24 +08:00
linonetwo
cec3834161 refactor(e2e): split timeouts into light (fixed) and heavy (calibrated)
Light operations (element finding, clicks, typing):
- PLAYWRIGHT_TIMEOUT: 10s fixed - fail fast on missing elements
- PLAYWRIGHT_SHORT_TIMEOUT: 5s - very fast checks

Heavy operations (app launch, page load, watch-fs):
- HEAVY_PLAYWRIGHT_TIMEOUT: calibrated - scales with hardware
- CUCUMBER_GLOBAL_TIMEOUT: calibrated - per-step budget
- LOG_MARKER_WAIT_TIMEOUT: calibrated - log markers

Also increase UI_RETRY_ATTEMPTS to compensate for shorter element timeouts
on slower machines (retries based on calibration multiplier).
2026-05-04 22:17:24 +08:00
linonetwo
fd9dbd254e refactor(e2e): recalibrate timeout system using CI measurements
Redesign based on actual CI data (calibration ≈ 20s, working timeout ≈ 62s):
- REFERENCE_CALIBRATION_MS=20000: baseline CI calibration time (1×)
- BASE_STEP_TIMEOUT_MS=60000: minimum step budget on baseline machine
- multiplier = measured_ms / REFERENCE_CALIBRATION_MS (no caps, no floors)
- CALIBRATION_PREFLIGHT_MULTIPLIER=10.0: only for measurement phase
- Missing calibration → throw error immediately (no silent fallback)

Also fix:
- Rename error-to-error-preflight.ts → end-to-end-calibration-preflight.ts
- Add .codenomad/ to .gitignore
- Remove BASE_TIMEOUT from timeouts.ts, import from calibration.ts instead
- Remove SAFETY_CAP, isCalibrated() checks
2026-05-04 21:13:48 +08:00
linonetwo
fb2a9b1f6e fix(e2e): run calibration twice, use max to capture CI variance
- Single calibration measurement misses transient CI load spikes

- Run smoke test 2×, use max duration for multiplier

- Accounts for variance without hardcoded buffer values

- Purely dynamic: multiplier adapts to actual worst-case performance
2026-05-04 18:15:49 +08:00
linonetwo
7a5b72edad refactor(e2e): remove all hardcoded timeout values, fully dynamic calibration
- smoke.feature: add filesystem watch enable/wait to measure worst-case ops

- calibration.ts: remove MIN_MULTIPLIER floor, MAX_MULTIPLIER cap

- calibration.ts: use SAFETY_CAP (20.0×) only as transient outlier guard

- calibration.ts: calibration preflight uses SAFETY_CAP, not hardcoded 10.0

- calibration.ts: fallback uses SAFETY_CAP, not hardcoded 4.0

- timeouts.ts: remove HEAVY_OPERATION_MULTIPLIER (1.6)

- timeouts.ts: heavy timeouts derive from calibration, not separate multiplier

- All timeouts now flow from single calibration measurement
2026-05-04 17:04:11 +08:00
linonetwo
f8ebf2fb0f fix(e2e): add minimum multiplier floor 4.0× for calibration
- Calibration smoke test only measures basic app launch

- Heavy operations (nsfw watcher) need more time than smoke test captures

- MIN_MULTIPLIER=4.0 ensures 100s minimum step timeout

- Actual multiplier: max(4.0, min(5.0, measured))

- Fast CI still gets 4.0×, very slow CI caps at 5.0×
2026-05-04 16:29:31 +08:00
linonetwo
7e51bf9e7c fix(e2e): enable calibration preflight in CI, remove separate script
- Remove CI skip in error-to-error-preflight.ts (was skipped with if(process.env.CI)return)

- Calibration now runs automatically as part of test:e2e npm script

- Use 10.0× (250s) timeout during calibration for first Electron launch

- Main tests use measured multiplier (capped at 5.0×)

- Remove standalone run-end-to-end-calibration.ts and test:e2e:calibration

- Remove separate workflow step, calibration is now built into e2e
2026-05-04 15:55:25 +08:00
linonetwo
fbf9182e1b fix(e2e): calibration should use fallback timeout, not special multiplier
- Remove TIDGI_E2E_IS_CALIBRATION env var from calibration script

- Remove special 10.0× multiplier logic from getPerformanceMultiplier()

- Calibration now uses normal 4.0× fallback timeout

- Measures actual duration and writes multiplier to file

- Main test reads calibration file for dynamic timeout
2026-05-02 01:02:56 +08:00
linonetwo
893e470f67 fix(e2e): increase calibration timeout to 10.0× for first-time init
- Calibration smoke test needs extra time for first Electron launch

- Use MAX_MULTIPLIER × 2.0 (10.0×) = 250s timeout during calibration

- Main test uses measured multiplier from calibration result

- Prevents calibration timeout on slow CI during cold start
2026-05-02 00:24:39 +08:00
linonetwo
31d2d148d6 rm ai mis-commit content 2026-05-02 00:15:09 +08:00
linonetwo
08e91cff53 refactor(ci): remove workflow timeout, rely on cucumber step timeouts
- Remove workflow-level timeout and env variables

- Each cucumber step has calibration-based timeout (max 125s)

- Step timeouts prevent infinite hangs without workflow timeout

- GitHub Actions default 360min job timeout as safety net

- Avoids hardcoded values, fully dynamic based on calibration
2026-05-01 23:36:50 +08:00
linonetwo
71dee95005 feat(ci): use calculated timeout from workflow env variables
- Add workflow-level env variables for timeout calculation constants

- BASE_TIMEOUT_MS: 25000, FALLBACK_MULTIPLIER: 4.0, SCENARIO_COUNT: 65

- E2E_TIMEOUT_MINUTES: 130 (calculated with 20% buffer)

- Use fromJSON(env.E2E_TIMEOUT_MINUTES) for dynamic timeout

- Update SCENARIO_COUNT when E2E suite grows, timeout auto-adjusts
2026-05-01 23:30:08 +08:00
linonetwo
fb12e74972 fix(ci): remove hardcoded timeout, use GitHub Actions default
- Remove timeout-minutes: 40 from E2E test step
- Let GitHub Actions use default 360 minute timeout
- Actual test duration controlled by calibration-based step timeouts
- Calibration dynamically adjusts timeouts based on CI performance
2026-05-01 23:26:54 +08:00
lin onetwo
e1746dde21 fix(analytics): remove API key from track requests, it is not needed
Rybbit /api/track is a public endpoint requiring only site_id, same as
data-site-id in <script> tags on websites. API keys are for reading data
via the dashboard API only. Embedding a key in Electron code is pointless
since the asar bundle is readable plain-text anyway.
2026-05-01 22:33:01 +08:00
lin onetwo
78e9ee5b9c feat(analytics): configure TidGi Desktop site credentials
- analyticsSiteId: 189dd97a8d37 (desktop.tidgi.fun on analytics.tidgi.fun)
- analyticsApiKey: TidGi Desktop API key (created 2026-05-01)
- analyticsHost: https://analytics.tidgi.fun (already set)

Tracking script (<script> tag) is for the tidgi.fun *website* only.
The desktop app uses fetch() API directly — no script tag needed.
2026-05-01 22:28:24 +08:00
lin onetwo
d9ae611e01 feat(analytics): stable device UUID for user identity, default host analytics.tidgi.fun
- Add deviceId field to IAnalyticsSecretSettings; generated once via
  crypto.randomUUID() and persisted to analyticsSecrets on first use
- Inject deviceId as user_id in every track payload so Rybbit groups
  all events from the same installation under one identified_user_id,
  independent of IP or User-Agent changes (proxy, network switch, etc.)
- Set default analyticsHost to https://analytics.tidgi.fun so
  installations without explicit env-var override point at the right server
2026-05-01 22:05:11 +08:00
linonetwo
c82be64705 fix(lint): fix calibration script lint errors
- Rename run-e2e-calibration.ts to run-end-to-end-calibration.ts (unicorn/prevent-abbreviations)
- Fix import order (fs-extra before node:child_process)
- Fix formatting (remove extra spaces, add trailing commas)
- Use void operator for floating promise (no-floating-promises)
- Update package.json script reference
2026-05-01 21:37:12 +08:00
linonetwo
c611ec5197 feat(e2e): implement calibration preflight for dynamic timeout calculation
- Add run-e2e-calibration.ts script to measure system performance via smoke test
- Add test:e2e:calibration npm script
- Update CI workflow to run calibration before full E2E suite
- Calibration measures actual performance and writes multiplier to .calibration.json
- Main E2E run reads calibration file for dynamic timeout scaling
- Falls back to 4.0× multiplier if calibration fails (continue-on-error: true)
- Removes hardcoded timeout assumptions, adapts to actual CI performance
2026-05-01 21:29:06 +08:00
linonetwo
5918e4f989 fix(e2e): increase fallback multiplier to 4.0× and workflow timeout to 40min
- Increase calibration fallback from 3.0× to 4.0× (100s per step) to accommodate
  slow native module initialization (nsfw watcher) in CI environments
- Update workflow timeout from 30min to 40min with calculation formula in comments
- Add guidance for future timeout adjustments based on scenario count growth
2026-05-01 19:12:01 +08:00
linonetwo
08d600cbdc Merge branch 'fix/misc-bug1' of https://github.com/tiddly-gittly/TidGi-Desktop into fix/misc-bug1 2026-05-01 18:32:52 +08:00
linonetwo
656fc7111a docs: simplify ai generated content 2026-05-01 18:32:48 +08:00
linonetwo
7a3528e76d refactor(e2e): remove CI-specific timeout handling, use calibration fallback
Remove hardcoded 1.5× multiplier for CI. Both CI and local dev now use
the same calibration-based timeout system. When calibration file is not
present (typical in CI), the system uses conservative 3.0× fallback
(75s timeout), which is sufficient for native module initialization.
2026-05-01 18:28:21 +08:00
linonetwo
7e188f4319 fix(e2e): increase CI timeout multiplier for native module operations
nsfw watcher initialization can take longer than 25s in CI environment,
causing filesystem watch tests to timeout. Increase CI multiplier from
1.0× to 1.5× (37.5s timeout) to accommodate native module startup time.
2026-04-30 09:31:06 +08:00
linonetwo
a6c1e60caf fix(test): add Analytics service mock to useTidgiConfigSync test 2026-04-30 08:42:30 +08:00
linonetwo
d3b8c8fee6 fix(lint): restore import order in window step definition 2026-04-30 08:22:48 +08:00
linonetwo
70075e43f1 chore: ignore cucumber-report.json in gitignore 2026-04-30 00:56:14 +08:00
linonetwo
54a1fa8196 refactor(wiki): extract bootWiki async function from Observable constructor
Move wiki boot logic out of Observable into standalone async function,
enabling natural async/await usage. Observable becomes thin orchestration layer
that handles debugger setup, stdout/stderr intercept, and error propagation.
2026-04-29 22:56:48 +08:00
linonetwo
1cda412d80 fix(wiki): replace async IIFE with Promise .then().catch() in Observable callback 2026-04-29 22:48:15 +08:00
linonetwo
2e21f0df30 fix(wiki): wrap async boot logic in IIFE to satisfy Observable type
Async Observable callbacks return Promise<void> which doesn't match
TeardownLogic. Use void IIFE pattern instead.
2026-04-29 22:43:04 +08:00
linonetwo
5da64f2c89 refactor(wiki): extract shared loadTiddlyWikiModule, use async dynamic import
- Move loadTiddlyWikiModule & authTokenIsProvided to loadTiddlyWikiModule.ts
- Replace local require() duplicate in htmlWiki.ts with shared async import
- Make Observable callback async in startNodeJSWiki.ts for await support
- Delete superseded wikiWorkerUtilities.ts
2026-04-29 22:37:35 +08:00
linonetwo
8193abae2c fix(e2e): fix workspace group plural mismatch; add backoff retry to browser view position checks 2026-04-29 22:34:08 +08:00
linonetwo
ae7a63ff23 refactor(wiki): extract shared async loadTiddlyWikiModule 2026-04-29 22:30:52 +08:00
linonetwo
1dd498fd4d fix(wiki): make Observable callback async to support await in startNodeJSWiki 2026-04-29 22:28:16 +08:00
linonetwo
8aec2d388c Revert "fix(e2e): prevent ELECTRON_RUN_AS_NODE from leaking into E2E launch env"
This reverts commit ca4382f23e.
2026-04-29 22:23:03 +08:00