Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
70 lines
3.6 KiB
TypeScript
70 lines
3.6 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import React, { act } from "react";
|
|
import { createDomRenderer, dispatchDomEvent, flushEffects, installDomEnvironment } from "./test-support/renderReactDom.tsx";
|
|
|
|
test("resume from another panel is visible while backend verification is pending", async (t) => {
|
|
const env = installDomEnvironment();
|
|
const previous = new Map<string, PropertyDescriptor | undefined>();
|
|
const globals = {
|
|
MutationObserver: env.window.MutationObserver,
|
|
NodeFilter: env.window.NodeFilter,
|
|
HTMLInputElement: env.window.HTMLInputElement,
|
|
Element: env.window.Element,
|
|
requestAnimationFrame: (callback: FrameRequestCallback) => setTimeout(() => callback(Date.now()), 0),
|
|
cancelAnimationFrame: clearTimeout,
|
|
};
|
|
for (const [key, value] of Object.entries(globals)) {
|
|
previous.set(key, Object.getOwnPropertyDescriptor(globalThis, key));
|
|
Object.defineProperty(globalThis, key, { configurable: true, writable: true, value });
|
|
}
|
|
Object.defineProperties(env.window.HTMLElement.prototype, {
|
|
offsetWidth: { configurable: true, get: () => 460 },
|
|
offsetHeight: { configurable: true, get() { return this.dataset.section === "global-sftp-transfer-list" ? 460 : 112; } },
|
|
});
|
|
const { I18nProvider } = await import("../application/i18n/I18nProvider.tsx");
|
|
const { sftpTransferCenterStore: store } = await import("../application/state/sftpTransferCenterStore.ts");
|
|
const { GlobalSftpTransferCenter } = await import("./GlobalSftpTransferCenter.tsx");
|
|
const { TooltipProvider } = await import("./ui/tooltip.tsx");
|
|
const renderer = await createDomRenderer(env.document);
|
|
t.after(async () => {
|
|
await renderer.unmount();
|
|
for (const [key, descriptor] of previous) {
|
|
if (descriptor) Object.defineProperty(globalThis, key, descriptor);
|
|
else Reflect.deleteProperty(globalThis, key);
|
|
}
|
|
env.cleanup();
|
|
});
|
|
let settleResume!: (result: { success: boolean }) => void;
|
|
let resumeCalls = 0;
|
|
const gate = new Promise<{ success: boolean }>((resolve) => { settleResume = resolve; });
|
|
Object.defineProperty(env.window, "netcatty", { configurable: true, value: {
|
|
resumeTransfer: async () => { resumeCalls += 1; return gate; },
|
|
} });
|
|
store.publishOwner("resume-display-test", [{
|
|
id: "resume-display", fileName: "resume-display.bin",
|
|
sourcePath: "/source.bin", targetPath: "/target.bin",
|
|
sourceConnectionId: "remote", targetConnectionId: "local", direction: "download",
|
|
status: "paused", totalBytes: 1000, transferredBytes: 100, speed: 0,
|
|
startTime: 1, isDirectory: false, resumable: true,
|
|
}]);
|
|
await renderer.render(<I18nProvider locale="en"><TooltipProvider><GlobalSftpTransferCenter /></TooltipProvider></I18nProvider>);
|
|
const toggle = env.document.querySelector("[data-section=global-sftp-transfer-toggle]");
|
|
assert.ok(toggle);
|
|
await dispatchDomEvent(toggle, new env.window.MouseEvent("click", { bubbles: true }));
|
|
let resumed!: Promise<void>;
|
|
await act(async () => { resumed = store.resume("resume-display"); });
|
|
try {
|
|
await flushEffects();
|
|
assert.equal(resumeCalls, 1);
|
|
const row = env.document.querySelector('[role=progressbar][aria-label="resume-display.bin"]')?.closest('[data-transfer-status]');
|
|
assert.ok(row);
|
|
assert.match(row.textContent ?? "", /Reconnecting and resuming/);
|
|
assert.equal(row.querySelector('button[aria-label="Resume"]'), null);
|
|
} finally {
|
|
await act(async () => { settleResume({ success: true }); await resumed; });
|
|
await dispatchDomEvent(toggle, new env.window.MouseEvent("click", { bubbles: true }));
|
|
await flushEffects();
|
|
}
|
|
});
|