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
119 lines
4.7 KiB
TypeScript
119 lines
4.7 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import React from "react";
|
|
|
|
import {
|
|
createDomRenderer,
|
|
dispatchDomEvent,
|
|
flushEffects,
|
|
installDomEnvironment,
|
|
} from "./test-support/renderReactDom.tsx";
|
|
|
|
test("associates the transfer-center folder warning with every destructive Replace action", async (t) => {
|
|
const env = installDomEnvironment();
|
|
const previousMutationObserver = globalThis.MutationObserver;
|
|
const previousNodeFilter = globalThis.NodeFilter;
|
|
const previousHTMLInputElement = globalThis.HTMLInputElement;
|
|
const previousElement = globalThis.Element;
|
|
const previousRequestAnimationFrame = globalThis.requestAnimationFrame;
|
|
const previousCancelAnimationFrame = globalThis.cancelAnimationFrame;
|
|
Object.defineProperties(globalThis, {
|
|
MutationObserver: { configurable: true, writable: true, value: env.window.MutationObserver },
|
|
NodeFilter: { configurable: true, writable: true, value: env.window.NodeFilter },
|
|
HTMLInputElement: { configurable: true, writable: true, value: env.window.HTMLInputElement },
|
|
Element: { configurable: true, writable: true, value: env.window.Element },
|
|
requestAnimationFrame: {
|
|
configurable: true,
|
|
writable: true,
|
|
value: (callback: FrameRequestCallback) => setTimeout(() => callback(Date.now()), 0),
|
|
},
|
|
cancelAnimationFrame: { configurable: true, writable: true, value: clearTimeout },
|
|
});
|
|
|
|
const { I18nProvider } = await import("../application/i18n/I18nProvider.tsx");
|
|
const { sftpTransferCenterStore } = 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);
|
|
const taskId = "accessible-folder-conflict";
|
|
const unregisterOwner = sftpTransferCenterStore.registerOwner("accessibility-test-owner", {
|
|
pause: () => {},
|
|
resume: () => {},
|
|
cancel: () => {},
|
|
retry: () => {},
|
|
prioritize: () => {},
|
|
dismiss: () => {},
|
|
ownsTask: () => true,
|
|
resolveConflict: () => {},
|
|
});
|
|
sftpTransferCenterStore.publishOwner("accessibility-test-owner", [{
|
|
id: taskId,
|
|
fileName: "docs",
|
|
sourcePath: "/source/docs",
|
|
targetPath: "/destination/docs",
|
|
sourceConnectionId: "source",
|
|
targetConnectionId: "target",
|
|
direction: "remote-to-remote",
|
|
status: "attention",
|
|
totalBytes: 0,
|
|
transferredBytes: 0,
|
|
speed: 0,
|
|
startTime: 1,
|
|
isDirectory: true,
|
|
conflict: {
|
|
transferId: taskId,
|
|
fileName: "docs",
|
|
sourcePath: "/source/docs",
|
|
targetPath: "/destination/docs",
|
|
isDirectory: true,
|
|
existingType: "directory",
|
|
applyToAllCount: 2,
|
|
existingSize: 0,
|
|
newSize: 0,
|
|
existingModified: 1,
|
|
newModified: 2,
|
|
},
|
|
}]);
|
|
|
|
t.after(async () => {
|
|
await renderer.unmount();
|
|
sftpTransferCenterStore.dismiss(taskId);
|
|
unregisterOwner();
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
Object.defineProperties(globalThis, {
|
|
MutationObserver: { configurable: true, writable: true, value: previousMutationObserver },
|
|
NodeFilter: { configurable: true, writable: true, value: previousNodeFilter },
|
|
HTMLInputElement: { configurable: true, writable: true, value: previousHTMLInputElement },
|
|
Element: { configurable: true, writable: true, value: previousElement },
|
|
requestAnimationFrame: { configurable: true, writable: true, value: previousRequestAnimationFrame },
|
|
cancelAnimationFrame: { configurable: true, writable: true, value: previousCancelAnimationFrame },
|
|
});
|
|
env.cleanup();
|
|
});
|
|
|
|
await renderer.render(React.createElement(
|
|
I18nProvider,
|
|
{ locale: "en" },
|
|
React.createElement(TooltipProvider, null, React.createElement(GlobalSftpTransferCenter)),
|
|
));
|
|
await flushEffects();
|
|
|
|
const toggle = env.document.querySelector<HTMLButtonElement>("[data-section=global-sftp-transfer-toggle]");
|
|
assert.ok(toggle, "transfer-center toggle should render");
|
|
await dispatchDomEvent(toggle, new env.window.MouseEvent("click", { bubbles: true }));
|
|
await flushEffects();
|
|
|
|
const replaceButtons = Array.from(env.document.querySelectorAll<HTMLButtonElement>("button"))
|
|
.filter((button) => button.textContent?.startsWith("Replace"));
|
|
assert.equal(replaceButtons.length, 2);
|
|
for (const button of replaceButtons) {
|
|
const describedBy = button.getAttribute("aria-describedby");
|
|
assert.ok(describedBy, `${button.textContent} should expose the folder deletion warning`);
|
|
const warning = env.document.getElementById(describedBy);
|
|
assert.match(
|
|
warning?.textContent ?? "",
|
|
/Replace: deletes destination-only content and cannot be undone/,
|
|
);
|
|
}
|
|
});
|