From 73334cbe8d7801abfe4d508c2d1ce7434e65975a Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 21 Jan 2025 23:30:36 -0800 Subject: [PATCH 1/3] added browser automation testing --- .vscode-test.mjs | 2 +- package-lock.json | 128 +++++++++++++++++++++++++++++++++++++-------- package.json | 2 + tsconfig.test.json | 6 ++- 4 files changed, 114 insertions(+), 24 deletions(-) diff --git a/.vscode-test.mjs b/.vscode-test.mjs index ce9992d0d1..c1a69e22df 100644 --- a/.vscode-test.mjs +++ b/.vscode-test.mjs @@ -2,7 +2,7 @@ import { defineConfig } from "@vscode/test-cli" import path from "path" export default defineConfig({ - files: "out/test/**/*.test.js", + files: "{out/test/**/*.test.js,src/test/suite/**/*.test.js}", mocha: { ui: "bdd", timeout: 20000, // Maximum time (in ms) that a test can run before failing diff --git a/package-lock.json b/package-lock.json index beb05b987e..6940e0d4d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,6 +49,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", "@types/node": "20.x", @@ -58,10 +59,9 @@ "@typescript-eslint/parser": "^7.11.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.4.0", + "chai": "^4.3.10", "esbuild": "^0.21.5", "eslint": "^8.57.0", - "glob": "^10.3.10", - "husky": "^9.1.7", "npm-run-all": "^4.1.5", "prettier": "^3.3.3", "should": "^13.2.3", @@ -4563,11 +4563,26 @@ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", "license": "MIT" }, + "node_modules/@types/chai": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.0.1.tgz", + "integrity": "sha512-5T8ajsg3M/FOncpLYW7sdOcD6yf4+722sze/tc4KQV0P8Z2rAr3SAuHCIkYmYpt8VbcQlnz8SxlOlPQYefe4cA==", + "dev": true, + "dependencies": { + "@types/deep-eql": "*" + } + }, "node_modules/@types/clone-deep": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/clone-deep/-/clone-deep-4.0.4.tgz", "integrity": "sha512-vXh6JuuaAha6sqEbJueYdh5zNBPPgG1OYumuz2UvLvriN6ABHDSW8ludREGWJb1MLIzbwZn4q4zUbUCerJTJfA==" }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true + }, "node_modules/@types/diff": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.2.1.tgz", @@ -5168,6 +5183,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/ast-types": { "version": "0.13.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", @@ -5517,6 +5541,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/chai": { + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5547,6 +5589,18 @@ "node": ">=8" } }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, "node_modules/cheerio": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", @@ -5941,6 +5995,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -7248,6 +7314,15 @@ "node": ">=18.11.0" } }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -7695,22 +7770,6 @@ "ms": "^2.0.0" } }, - "node_modules/husky": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", - "dev": true, - "license": "MIT", - "bin": { - "husky": "bin.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -8502,6 +8561,15 @@ "underscore": "^1.13.1" } }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, "node_modules/lru-cache": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", @@ -9738,6 +9806,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, "node_modules/pdf-parse": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-1.1.1.tgz", @@ -11117,6 +11194,15 @@ "node": ">= 0.8.0" } }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -11284,9 +11370,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "6.21.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", - "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.8.tgz", + "integrity": "sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==", "license": "MIT", "engines": { "node": ">=18.17" diff --git a/package.json b/package.json index 7cc5d11d49..67be71e4ca 100644 --- a/package.json +++ b/package.json @@ -168,6 +168,7 @@ "prepare": "husky" }, "devDependencies": { + "@types/chai": "^5.0.1", "@types/diff": "^5.2.1", "@types/mocha": "^10.0.7", "@types/node": "20.x", @@ -177,6 +178,7 @@ "@typescript-eslint/parser": "^7.11.0", "@vscode/test-cli": "^0.0.9", "@vscode/test-electron": "^2.4.0", + "chai": "^4.3.10", "esbuild": "^0.21.5", "eslint": "^8.57.0", "husky": "^9.1.7", diff --git a/tsconfig.test.json b/tsconfig.test.json index 45dd541b8b..92f67542f5 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -8,9 +8,11 @@ "compilerOptions": { "module": "commonjs", "moduleResolution": "node", - "types": ["node", "mocha", "should", "vscode"], + "types": ["node", "mocha", "should", "vscode", "chai"], + "typeRoots": ["./node_modules/@types", "./src/test/types"], "outDir": "out", "rootDir": "src" }, - "include": ["src/**/*.test.ts"] + "include": ["src/**/*.test.ts"], + "exclude": ["src/test/**/*.js"] } From a5bfd74c6d171efd648edf2a7b592cc97105338d Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 21 Jan 2025 23:40:48 -0800 Subject: [PATCH 2/3] forgot the actual files --- src/test/suite/extension.test.js | 37 +++++++++++++++++++++++++++ src/test/suite/index.js | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/test/suite/extension.test.js create mode 100644 src/test/suite/index.js diff --git a/src/test/suite/extension.test.js b/src/test/suite/extension.test.js new file mode 100644 index 0000000000..b8ddff26c6 --- /dev/null +++ b/src/test/suite/extension.test.js @@ -0,0 +1,37 @@ +const { expect } = require('chai'); +const vscode = require('vscode'); + +describe('Extension Tests', function() { + this.timeout(60000); // Increased timeout for extension operations + + it('should activate extension successfully', async () => { + // Get the extension + const extension = vscode.extensions.getExtension('saoudrizwan.claude-dev'); + expect(extension).to.not.be.undefined; + + // Activate the extension if not already activated + if (!extension.isActive) { + await extension.activate(); + } + expect(extension.isActive).to.be.true; + }); + + it('should open sidebar view', async () => { + // Execute the command to open sidebar + await vscode.commands.executeCommand('cline.plusButtonClicked'); + + // Wait for sidebar to be visible + await new Promise(resolve => setTimeout(resolve, 1000)); + + // Get all views + const views = vscode.window.visibleTextEditors; + // Just verify the command executed without error + // The actual view verification is handled in the TypeScript tests + }); + + it('should handle basic commands', async () => { + // Test basic command execution + await vscode.commands.executeCommand('cline.historyButtonClicked'); + // Success if no error thrown + }); +}); diff --git a/src/test/suite/index.js b/src/test/suite/index.js new file mode 100644 index 0000000000..50c997b131 --- /dev/null +++ b/src/test/suite/index.js @@ -0,0 +1,43 @@ +const path = require('path'); +const Mocha = require('mocha'); +const glob = require('glob'); + +async function run() { + // Create the mocha test + const mocha = new Mocha({ + ui: 'bdd', + color: true, + timeout: 60000 // Increased timeout for extension operations + }); + + const testsRoot = path.resolve(__dirname, '.'); + + try { + // Find all test files + const files = await glob('*.test.js', { cwd: testsRoot }); + + // Add files to the test suite + files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); + + // Run the mocha test + return new Promise((resolve, reject) => { + try { + // Run the tests + mocha.run(failures => { + if (failures > 0) { + reject(new Error(`${failures} tests failed.`)); + } else { + resolve(); + } + }); + } catch (err) { + reject(err); + } + }); + } catch (err) { + console.error('Failed to run tests:', err); + throw err; + } +} + +module.exports = { run }; From 561f688e2a3f06e1841aa8f2cfdd7ecd2793267f Mon Sep 17 00:00:00 2001 From: Ocasta Date: Tue, 21 Jan 2025 23:44:08 -0800 Subject: [PATCH 3/3] prettier --- package-lock.json | 20 ++++++++- src/test/suite/extension.test.js | 70 ++++++++++++++++---------------- src/test/suite/index.js | 70 ++++++++++++++++---------------- 3 files changed, 88 insertions(+), 72 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6940e0d4d7..c16b15f88e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claude-dev", - "version": "3.2.4", + "version": "3.2.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claude-dev", - "version": "3.2.4", + "version": "3.2.5", "license": "Apache-2.0", "dependencies": { "@anthropic-ai/bedrock-sdk": "^0.10.2", @@ -62,6 +62,7 @@ "chai": "^4.3.10", "esbuild": "^0.21.5", "eslint": "^8.57.0", + "husky": "^9.1.7", "npm-run-all": "^4.1.5", "prettier": "^3.3.3", "should": "^13.2.3", @@ -7770,6 +7771,21 @@ "ms": "^2.0.0" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", diff --git a/src/test/suite/extension.test.js b/src/test/suite/extension.test.js index b8ddff26c6..f9d3305db0 100644 --- a/src/test/suite/extension.test.js +++ b/src/test/suite/extension.test.js @@ -1,37 +1,37 @@ -const { expect } = require('chai'); -const vscode = require('vscode'); +const { expect } = require("chai") +const vscode = require("vscode") -describe('Extension Tests', function() { - this.timeout(60000); // Increased timeout for extension operations +describe("Extension Tests", function () { + this.timeout(60000) // Increased timeout for extension operations - it('should activate extension successfully', async () => { - // Get the extension - const extension = vscode.extensions.getExtension('saoudrizwan.claude-dev'); - expect(extension).to.not.be.undefined; - - // Activate the extension if not already activated - if (!extension.isActive) { - await extension.activate(); - } - expect(extension.isActive).to.be.true; - }); - - it('should open sidebar view', async () => { - // Execute the command to open sidebar - await vscode.commands.executeCommand('cline.plusButtonClicked'); - - // Wait for sidebar to be visible - await new Promise(resolve => setTimeout(resolve, 1000)); - - // Get all views - const views = vscode.window.visibleTextEditors; - // Just verify the command executed without error - // The actual view verification is handled in the TypeScript tests - }); - - it('should handle basic commands', async () => { - // Test basic command execution - await vscode.commands.executeCommand('cline.historyButtonClicked'); - // Success if no error thrown - }); -}); + it("should activate extension successfully", async () => { + // Get the extension + const extension = vscode.extensions.getExtension("saoudrizwan.claude-dev") + expect(extension).to.not.be.undefined + + // Activate the extension if not already activated + if (!extension.isActive) { + await extension.activate() + } + expect(extension.isActive).to.be.true + }) + + it("should open sidebar view", async () => { + // Execute the command to open sidebar + await vscode.commands.executeCommand("cline.plusButtonClicked") + + // Wait for sidebar to be visible + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Get all views + const views = vscode.window.visibleTextEditors + // Just verify the command executed without error + // The actual view verification is handled in the TypeScript tests + }) + + it("should handle basic commands", async () => { + // Test basic command execution + await vscode.commands.executeCommand("cline.historyButtonClicked") + // Success if no error thrown + }) +}) diff --git a/src/test/suite/index.js b/src/test/suite/index.js index 50c997b131..36dccbf9f0 100644 --- a/src/test/suite/index.js +++ b/src/test/suite/index.js @@ -1,43 +1,43 @@ -const path = require('path'); -const Mocha = require('mocha'); -const glob = require('glob'); +const path = require("path") +const Mocha = require("mocha") +const glob = require("glob") async function run() { - // Create the mocha test - const mocha = new Mocha({ - ui: 'bdd', - color: true, - timeout: 60000 // Increased timeout for extension operations - }); + // Create the mocha test + const mocha = new Mocha({ + ui: "bdd", + color: true, + timeout: 60000, // Increased timeout for extension operations + }) - const testsRoot = path.resolve(__dirname, '.'); + const testsRoot = path.resolve(__dirname, ".") - try { - // Find all test files - const files = await glob('*.test.js', { cwd: testsRoot }); + try { + // Find all test files + const files = await glob("*.test.js", { cwd: testsRoot }) - // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); + // Add files to the test suite + files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))) - // Run the mocha test - return new Promise((resolve, reject) => { - try { - // Run the tests - mocha.run(failures => { - if (failures > 0) { - reject(new Error(`${failures} tests failed.`)); - } else { - resolve(); - } - }); - } catch (err) { - reject(err); - } - }); - } catch (err) { - console.error('Failed to run tests:', err); - throw err; - } + // Run the mocha test + return new Promise((resolve, reject) => { + try { + // Run the tests + mocha.run((failures) => { + if (failures > 0) { + reject(new Error(`${failures} tests failed.`)) + } else { + resolve() + } + }) + } catch (err) { + reject(err) + } + }) + } catch (err) { + console.error("Failed to run tests:", err) + throw err + } } -module.exports = { run }; +module.exports = { run }