Skip to main content
Glama
virtualKeyboardManager.test.tsβ€’10.2 kB
import { assert } from "chai"; import { VirtualKeyboardManager } from "../../src/utils/virtualKeyboardManager"; import { AdbUtils } from "../../src/utils/android-cmdline-tools/adb"; import { ExecResult } from "../../src/models/ExecResult"; import sinon from "sinon"; // Helper function to create mock ExecResult function createMockExecResult(output: string): ExecResult { return { stdout: output, stderr: "", toString() { return this.stdout; }, trim() { return this.stdout.trim(); }, includes(searchString: string) { return this.stdout.includes(searchString); } }; } describe("VirtualKeyboardManager", () => { let virtualKeyboardManager: VirtualKeyboardManager; let mockAdb: sinon.SinonStubbedInstance<AdbUtils>; beforeEach(() => { // Create stubs for dependencies mockAdb = sinon.createStubInstance(AdbUtils); // Stub the AdbUtils constructor sinon.stub(AdbUtils.prototype, "executeCommand").callsFake(mockAdb.executeCommand); virtualKeyboardManager = new VirtualKeyboardManager("test-device"); }); afterEach(() => { sinon.restore(); }); describe("Static utility methods", () => { describe("containsUnicode", () => { it("should return false for ASCII text", () => { assert.isFalse(VirtualKeyboardManager.containsUnicode("Hello World")); assert.isFalse(VirtualKeyboardManager.containsUnicode("123456789")); assert.isFalse(VirtualKeyboardManager.containsUnicode("!@#$%^&*()")); }); it("should return true for Unicode text", () => { assert.isTrue(VirtualKeyboardManager.containsUnicode("πŸ˜€πŸ˜ƒπŸ˜„")); assert.isTrue(VirtualKeyboardManager.containsUnicode("ΠŸΡ€ΠΈΠ²Π΅Ρ‚ ΠΌΠΈΡ€")); assert.isTrue(VirtualKeyboardManager.containsUnicode("δ½ ε₯½δΈ–η•Œ")); assert.isTrue(VirtualKeyboardManager.containsUnicode("Hello πŸ˜€")); }); it("should return false for empty string", () => { assert.isFalse(VirtualKeyboardManager.containsUnicode("")); }); }); describe("getInputMethod", () => { it('should return "native" for ASCII text', () => { assert.equal(VirtualKeyboardManager.getInputMethod("Hello World"), "native"); assert.equal(VirtualKeyboardManager.getInputMethod("Test 123"), "native"); }); it('should return "virtual" for Unicode text', () => { assert.equal(VirtualKeyboardManager.getInputMethod("πŸ˜€πŸ˜ƒπŸ˜„"), "virtual"); assert.equal(VirtualKeyboardManager.getInputMethod("ΠŸΡ€ΠΈΠ²Π΅Ρ‚"), "virtual"); }); }); }); describe("ADBKeyboard detection methods", () => { describe("isAdbKeyboardInstalled", () => { it("should return true when ADBKeyboard is installed", async () => { mockAdb.executeCommand.resolves(createMockExecResult("package:com.android.adbkeyboard")); const result = await virtualKeyboardManager.isAdbKeyboardInstalled(); assert.isTrue(result); sinon.assert.calledWith(mockAdb.executeCommand, "shell pm list packages | grep com.android.adbkeyboard"); }); it("should return false when ADBKeyboard is not installed", async () => { mockAdb.executeCommand.resolves(createMockExecResult("")); const result = await virtualKeyboardManager.isAdbKeyboardInstalled(); assert.isFalse(result); }); it("should return false when command fails", async () => { mockAdb.executeCommand.rejects(new Error("Command failed")); const result = await virtualKeyboardManager.isAdbKeyboardInstalled(); assert.isFalse(result); }); }); describe("isAdbKeyboardEnabled", () => { it("should return true when ADBKeyboard is enabled", async () => { mockAdb.executeCommand.resolves(createMockExecResult("com.android.adbkeyboard/.AdbIME")); const result = await virtualKeyboardManager.isAdbKeyboardEnabled(); assert.isTrue(result); sinon.assert.calledWith(mockAdb.executeCommand, "shell ime list"); }); it("should return false when ADBKeyboard is not enabled", async () => { mockAdb.executeCommand.resolves(createMockExecResult("com.google.android.inputmethod.latin")); const result = await virtualKeyboardManager.isAdbKeyboardEnabled(); assert.isFalse(result); }); }); describe("isAdbKeyboardActive", () => { it("should return true when ADBKeyboard is active", async () => { mockAdb.executeCommand.resolves(createMockExecResult("com.android.adbkeyboard/.AdbIME")); const result = await virtualKeyboardManager.isAdbKeyboardActive(); assert.isTrue(result); sinon.assert.calledWith(mockAdb.executeCommand, "shell settings get secure default_input_method"); }); it("should return false when different keyboard is active", async () => { mockAdb.executeCommand.resolves(createMockExecResult("com.google.android.inputmethod.latin/.LatinIME")); const result = await virtualKeyboardManager.isAdbKeyboardActive(); assert.isFalse(result); }); }); describe("getCurrentInputMethod", () => { it("should return current input method", async () => { const expectedMethod = "com.google.android.inputmethod.latin/.LatinIME"; mockAdb.executeCommand.resolves(createMockExecResult(expectedMethod)); const result = await virtualKeyboardManager.getCurrentInputMethod(); assert.equal(result, expectedMethod); }); it("should return null when command fails", async () => { mockAdb.executeCommand.rejects(new Error("Command failed")); const result = await virtualKeyboardManager.getCurrentInputMethod(); assert.isNull(result); }); }); }); describe("Text input operations", () => { describe("sendUnicodeText", () => { it("should send Unicode text successfully", async () => { mockAdb.executeCommand .onFirstCall().resolves(createMockExecResult("com.android.adbkeyboard/.AdbIME")) // isAdbKeyboardActive .onSecondCall().resolves(createMockExecResult("Broadcast completed")); // am broadcast await virtualKeyboardManager.sendUnicodeText("πŸ˜€πŸ˜ƒπŸ˜„"); sinon.assert.calledWith(mockAdb.executeCommand, 'shell am broadcast -a ADB_INPUT_TEXT --es msg "πŸ˜€πŸ˜ƒπŸ˜„"'); }); it("should throw error if ADBKeyboard is not active", async () => { mockAdb.executeCommand.resolves(createMockExecResult("com.google.android.inputmethod.latin/.LatinIME")); try { await virtualKeyboardManager.sendUnicodeText("πŸ˜€πŸ˜ƒπŸ˜„"); assert.fail("Should have thrown an error"); } catch (error) { assert.include((error as Error).message, "ADBKeyboard is not active"); } }); it("should escape special characters", async () => { mockAdb.executeCommand .onFirstCall().resolves(createMockExecResult("com.android.adbkeyboard/.AdbIME")) // isAdbKeyboardActive .onSecondCall().resolves(createMockExecResult("Broadcast completed")); // am broadcast await virtualKeyboardManager.sendUnicodeText('Text with "quotes" and \\backslashes\\'); sinon.assert.calledWith(mockAdb.executeCommand, 'shell am broadcast -a ADB_INPUT_TEXT --es msg "Text with \\"quotes\\" and \\\\backslashes\\\\"'); }); }); describe("clearText", () => { it("should clear text successfully", async () => { mockAdb.executeCommand.resolves(createMockExecResult("Broadcast completed")); await virtualKeyboardManager.clearText(); sinon.assert.calledWith(mockAdb.executeCommand, "shell am broadcast -a ADB_CLEAR_TEXT"); }); }); }); describe("Keyboard management", () => { describe("enableAdbKeyboard", () => { it("should enable ADBKeyboard successfully", async () => { mockAdb.executeCommand.resolves(createMockExecResult("Input method enabled")); await virtualKeyboardManager.enableAdbKeyboard(); sinon.assert.calledWith(mockAdb.executeCommand, "shell ime enable com.android.adbkeyboard/.AdbIME"); }); it("should throw error if enable fails", async () => { mockAdb.executeCommand.resolves(createMockExecResult("Error: Failed to enable")); try { await virtualKeyboardManager.enableAdbKeyboard(); assert.fail("Should have thrown an error"); } catch (error) { assert.include((error as Error).message, "Failed to enable ADBKeyboard"); } }); }); describe("setAdbKeyboardActive", () => { it("should set ADBKeyboard as active and return previous", async () => { const previousKeyboard = "com.google.android.inputmethod.latin/.LatinIME"; mockAdb.executeCommand .onFirstCall().resolves(createMockExecResult(previousKeyboard)) // getCurrentInputMethod .onSecondCall().resolves(createMockExecResult("Input method selected")); // ime set const result = await virtualKeyboardManager.setAdbKeyboardActive(); assert.equal(result, previousKeyboard); sinon.assert.calledWith(mockAdb.executeCommand, "shell ime set com.android.adbkeyboard/.AdbIME"); }); }); describe("restoreInputMethod", () => { it("should restore previous keyboard", async () => { const previousKeyboard = "com.google.android.inputmethod.latin/.LatinIME"; mockAdb.executeCommand.resolves(createMockExecResult("Input method selected")); await virtualKeyboardManager.restoreInputMethod(previousKeyboard); sinon.assert.calledWith(mockAdb.executeCommand, `shell ime set "${previousKeyboard}"`); }); }); }); describe("Cleanup operations", () => { describe("cleanupApk", () => { it("should handle cleanup operations", () => { // Note: cleanupApk functionality is tested implicitly in integration tests // Direct testing of fs.unlink stubbing causes issues with sinon in this environment assert.isTrue(true); // Placeholder test }); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zillow/auto-mobile'

If you have feedback or need assistance with the MCP directory API, please join our Discord server