Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

detox-copilot

Package Overview
Dependencies
Maintainers
2
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

detox-copilot - npm Package Compare versions

Comparing version 0.0.11 to 0.0.13

4

dist/actions/StepPerformer.js

@@ -60,3 +60,3 @@ "use strict";

catch (error) {
console.error('Error loading cache from file:', error);
console.warn('Error loading cache from file:', error);
this.cache.clear(); // Clear cache on error to avoid stale data

@@ -79,3 +79,3 @@ }

this.loadCacheFromFile();
const snapshot = await this.snapshotManager.captureSnapshotImage();
const snapshot = this.promptHandler.isSnapshotImageSupported() ? await this.snapshotManager.captureSnapshotImage() : undefined;
const viewHierarchy = await this.snapshotManager.captureViewHierarchyString();

@@ -82,0 +82,0 @@ const isSnapshotImageAttached = snapshot != null && this.promptHandler.isSnapshotImageSupported();

@@ -106,3 +106,3 @@ "use strict";

expect(mockPromptCreator.createPrompt).toHaveBeenCalledWith(intent, '<view></view>', false, []);
expect(mockPromptHandler.runPrompt).toHaveBeenCalledWith('generated prompt', 'snapshot_data');
expect(mockPromptHandler.runPrompt).toHaveBeenCalledWith('generated prompt', undefined);
expect(mockCodeEvaluator.evaluate).toHaveBeenCalledWith('generated code', mockContext);

@@ -109,0 +109,0 @@ expect(fs.writeFileSync).toHaveBeenCalled();

@@ -8,8 +8,11 @@ "use strict";

const Copilot_1 = require("../Copilot");
jest.mock('fs', () => ({
readFileSync: jest.fn().mockReturnValue('{}')
}));
describe('Integration', () => {
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
jest.mock('fs');
jest.mock('path');
describe('Copilot Integration Tests', () => {
let mockFrameworkDriver;
let mockPromptHandler;
let mockFs;
let mockPath;
beforeEach(() => {

@@ -29,13 +32,24 @@ jest.clearAllMocks();

};
mockFs = fs_1.default;
mockPath = path_1.default;
mockFs.existsSync.mockReturnValue(false);
mockFs.readFileSync.mockReturnValue('{}');
mockFs.writeFileSync.mockImplementation(() => { });
mockPath.resolve.mockImplementation((...paths) => paths.join('/'));
});
afterEach(() => {
// Reset Copilot instance after each test to ensure a clean state
Copilot_1.Copilot['instance'] = undefined;
});
describe('Initialization', () => {
it('should synchronously throw an error when perform is called before initialization', async () => {
it('should throw an error when perform is called before initialization', async () => {
await expect(() => index_1.default.perform('Some action')).rejects.toThrow();
});
it('should initialize successfully', () => {
expect(() => index_1.default.init({
frameworkDriver: mockFrameworkDriver,
promptHandler: mockPromptHandler
})).not.toThrow();
});
});
describe('perform method', () => {
describe('Single Step Operations', () => {
beforeEach(() => {

@@ -74,3 +88,3 @@ index_1.default.init({

});
describe('error handling', () => {
describe('Multiple Step Operations', () => {
beforeEach(() => {

@@ -82,2 +96,32 @@ index_1.default.init({

});
it('should perform multiple steps using spread operator', async () => {
mockPromptHandler.runPrompt
.mockResolvedValueOnce('// Tap login button')
.mockResolvedValueOnce('// Enter username')
.mockResolvedValueOnce('// Enter password');
const results = await index_1.default.perform('Tap on the login button', 'Enter username "testuser"', 'Enter password "password123"');
expect(results).toHaveLength(3);
expect(mockPromptHandler.runPrompt).toHaveBeenCalledTimes(3);
expect(mockFrameworkDriver.captureSnapshotImage).toHaveBeenCalledTimes(3);
expect(mockFrameworkDriver.captureViewHierarchyString).toHaveBeenCalledTimes(3);
});
it('should handle errors in multiple steps and stop execution', async () => {
mockPromptHandler.runPrompt
.mockResolvedValueOnce('// Tap login button')
.mockResolvedValueOnce('throw new Error("Username field not found");')
.mockResolvedValueOnce('throw new Error("Username field not found - second");')
.mockResolvedValueOnce('// Enter password');
await expect(index_1.default.perform('Tap on the login button', 'Enter username "testuser"', 'Enter password "password123"')).rejects.toThrow('Username field not found');
expect(mockPromptHandler.runPrompt).toHaveBeenCalledTimes(3);
expect(mockFrameworkDriver.captureSnapshotImage).toHaveBeenCalledTimes(2);
expect(mockFrameworkDriver.captureViewHierarchyString).toHaveBeenCalledTimes(2);
});
});
describe('Error Handling', () => {
beforeEach(() => {
index_1.default.init({
frameworkDriver: mockFrameworkDriver,
promptHandler: mockPromptHandler
});
});
it('should throw error when PromptHandler fails', async () => {

@@ -96,2 +140,92 @@ mockPromptHandler.runPrompt.mockRejectedValue(new Error('API error'));

});
describe('Context Management', () => {
beforeEach(() => {
index_1.default.init({
frameworkDriver: mockFrameworkDriver,
promptHandler: mockPromptHandler
});
});
it('should reset context when reset is called', async () => {
mockPromptHandler.runPrompt.mockResolvedValueOnce('// Login action');
await index_1.default.perform('Log in to the application');
index_1.default.reset();
mockPromptHandler.runPrompt.mockResolvedValueOnce('// New action after reset');
await index_1.default.perform('Perform action after reset');
expect(mockPromptHandler.runPrompt).toHaveBeenCalledTimes(2);
expect(mockPromptHandler.runPrompt.mock.calls[1][0]).not.toContain('Log in to the application');
});
it('should clear conversation history on reset', async () => {
mockPromptHandler.runPrompt
.mockResolvedValueOnce('// Action 1')
.mockResolvedValueOnce('// Action 2');
await index_1.default.perform('Action 1');
await index_1.default.perform('Action 2');
const lastCallArgsBeforeReset = mockPromptHandler.runPrompt.mock.calls[1][0];
expect(lastCallArgsBeforeReset).toContain('Action 1');
expect(lastCallArgsBeforeReset).toContain('Action 2');
index_1.default.reset();
mockPromptHandler.runPrompt.mockResolvedValueOnce('// New action');
await index_1.default.perform('New action after reset');
const lastCallArgsAfterReset = mockPromptHandler.runPrompt.mock.calls[2][0];
expect(lastCallArgsAfterReset).not.toContain('Action 1');
expect(lastCallArgsAfterReset).not.toContain('Action 2');
expect(lastCallArgsAfterReset).toContain('New action after reset');
});
});
describe('Caching Behavior', () => {
beforeEach(() => {
index_1.default.init({
frameworkDriver: mockFrameworkDriver,
promptHandler: mockPromptHandler
});
});
it('should create cache file if it does not exist', async () => {
mockFs.existsSync.mockReturnValue(false);
mockPromptHandler.runPrompt.mockResolvedValue('// Perform action');
await index_1.default.perform('Perform action');
expect(mockFs.writeFileSync).toHaveBeenCalled();
});
it('should read from existing cache file', async () => {
mockFs.existsSync.mockReturnValue(true);
mockFs.readFileSync.mockReturnValue(JSON.stringify({
'{"step":"Cached action","previous":[]}': '// Cached action code'
}));
await index_1.default.perform('Cached action');
expect(mockFs.readFileSync).toHaveBeenCalled();
expect(mockPromptHandler.runPrompt).not.toHaveBeenCalled();
});
it('should update cache file after performing new action', async () => {
mockPromptHandler.runPrompt.mockResolvedValue('// New action code');
await index_1.default.perform('New action');
expect(mockFs.writeFileSync).toHaveBeenCalledWith(expect.any(String), expect.stringContaining('New action'), expect.any(Object));
});
it('should handle fs.readFileSync errors', async () => {
mockFs.existsSync.mockReturnValue(true);
mockFs.readFileSync.mockImplementation(() => { throw new Error('Read error'); });
mockPromptHandler.runPrompt.mockResolvedValue('// New action code');
await index_1.default.perform('Action with read error');
expect(mockPromptHandler.runPrompt).toHaveBeenCalled();
});
it('should handle fs.writeFileSync errors', async () => {
mockFs.writeFileSync.mockImplementation(() => { throw new Error('Write error'); });
mockPromptHandler.runPrompt.mockResolvedValue('// Action code');
await expect(index_1.default.perform('Action with write error')).resolves.not.toThrow();
});
});
describe('Feature Support', () => {
beforeEach(() => {
index_1.default.init({
frameworkDriver: mockFrameworkDriver,
promptHandler: mockPromptHandler
});
});
it('should work without snapshot images when not supported', async () => {
mockPromptHandler.isSnapshotImageSupported.mockReturnValue(false);
mockPromptHandler.runPrompt.mockResolvedValue('// Perform action without snapshot');
await index_1.default.perform('Perform action without snapshot support');
expect(mockFrameworkDriver.captureSnapshotImage).not.toHaveBeenCalled();
expect(mockFrameworkDriver.captureViewHierarchyString).toHaveBeenCalled();
expect(mockPromptHandler.runPrompt).toHaveBeenCalledWith(expect.stringContaining('Perform action without snapshot support'), undefined);
});
});
});
{
"name": "detox-copilot",
"version": "0.0.11",
"version": "0.0.13",
"description": "A flexible plugin that drives your tests with human-written commands, enhanced by the power of large language models (LLMs)",

@@ -5,0 +5,0 @@ "keywords": [

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc