Files
KanbanGit/native/src-tauri/tests/updater_smoke.rs
T
Twyco f6725ac025
CI/CD / preconditions (pull_request) Successful in 2s
Native JavaScript checks / Native launcher and release tests (pull_request) Successful in 58s
macOS checks / Native Rust tests and unsigned build (pull_request) Successful in 2m0s
CI/CD / test_and_check_app (pull_request) Successful in 6m28s
CI/CD / Publish immutable image (pull_request) Skipped
fix(KAN-65): show the installed macOS build number
2026-09-27 22:42:01 +02:00

83 lines
4.8 KiB
Rust

#[cfg(target_os = "macos")]
#[tauri::command]
fn updater_smoke_report(app: tauri::AppHandle, passed: bool, reason: String) {
use tauri::Manager;
println!("Updater WebView test: passed={passed}, {reason}");
app.state::<std::sync::Arc<std::sync::atomic::AtomicBool>>()
.store(passed, std::sync::atomic::Ordering::SeqCst);
app.exit(if passed { 0 } else { 1 });
}
#[cfg(target_os = "macos")]
fn main() {
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use tauri::webview::PageLoadEvent;
let passed = Arc::new(AtomicBool::new(false));
let config: serde_json::Value =
serde_json::from_str(include_str!("../tauri.conf.json")).unwrap();
let expected_installed = format!(
"Installed version {} (build {})",
config["version"].as_str().unwrap(),
config["bundle"]["macOS"]["bundleVersion"].as_str().unwrap()
);
let plugin = tauri::plugin::Builder::<tauri::Wry>::new("updater-smoke")
.js_init_script(format!("window.expectedInstalled = {};", serde_json::to_string(&expected_installed).unwrap()))
.on_page_load(|window, payload| {
if window.label() != "updates" || payload.event() != PageLoadEvent::Finished { return; }
window.eval(r#"
(async () => {
try {
for (let i = 0; i < 100 && !window.updateStatus; i++) await new Promise(r => setTimeout(r, 50));
if (!window.updateStatus) throw new Error('Update UI did not load');
const $ = id => document.getElementById(id);
for (let i = 0; i < 100 && !$('installed').textContent; i++) await new Promise(r => setTimeout(r, 50));
if ($('installed').textContent !== window.expectedInstalled) throw new Error('Actual installed version/build failed: ' + $('installed').textContent);
const state = { phase: 'current', currentVersion: '0.1.2', build: '2', version: null, notes: null, downloaded: 0, total: null, error: null, preferences: { automatic: true, intervalHours: 6 } };
window.updateStatus(state);
if (!$('installed').textContent.includes('0.1.2 (build 2)') || !$('install').hidden || $('check').disabled) throw new Error('Current version state failed');
Object.assign(state, { phase: 'available', version: '0.1.3', notes: '<script>unsafe()</script>\nRelease notes' });
window.updateStatus(state);
if ($('install').hidden || $('release-notes').querySelector('script') || !$('release-notes').textContent.includes('<script>')) throw new Error('Available state or text escaping failed');
$('install').click();
if ($('install-confirmation').hidden || !$('install-confirmation').textContent.includes('Unsaved inputs')) throw new Error('Missing restart confirmation');
$('cancel-install').click();
if (!$('install-confirmation').hidden) throw new Error('Cancel failed');
Object.assign(state, { phase: 'downloading', downloaded: 500, total: 1000 }); window.updateStatus(state);
if (!$('check').disabled || !$('install').hidden || $('download-progress').value !== 500) throw new Error('Progress state failed');
Object.assign(state, { phase: 'error', error: 'signatureError' }); window.updateStatus(state);
if ($('install').hidden || !$('update-error').textContent.includes('Nothing was installed')) throw new Error('Retry failed');
state.preferences.automatic = false; window.updateStatus(state);
if ($('automatic').checked || !$('interval').disabled) throw new Error('Opt out failed');
await window.__TAURI_INTERNALS__.invoke('updater_smoke_report', { passed: true, reason: '' });
} catch (error) {
await window.__TAURI_INTERNALS__.invoke('updater_smoke_report', { passed: false, reason: error.message });
}
})();
"#).unwrap();
})
.build();
let mut context = kanbangit_native::context();
context.config_mut().identifier = format!("de.kanbangit.smoke.updates.{}", std::process::id());
let app = kanbangit_native::builder()
.manage(passed.clone())
.invoke_handler(tauri::generate_handler![updater_smoke_report])
.plugin(plugin)
.build(context)
.expect("App must start");
let handle = app.handle().clone();
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_secs(30));
handle.exit(1);
});
app.run_return(|_, _| {});
assert!(passed.load(Ordering::SeqCst), "Updater UI test must pass");
}
#[cfg(not(target_os = "macos"))]
fn main() {
panic!("Requires macOS");
}