mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 04:11:10 -05:00
Merge pull request #691 from RooVetGit/cte/integration-tests
This commit is contained in:
1
.env.integration.example
Normal file
1
.env.integration.example
Normal file
@@ -0,0 +1 @@
|
|||||||
|
OPENROUTER_API_KEY=sk-or-v1-...
|
||||||
37
.github/workflows/code-qa.yml
vendored
37
.github/workflows/code-qa.yml
vendored
@@ -1,6 +1,7 @@
|
|||||||
name: Code QA Roo Code
|
name: Code QA Roo Code
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
pull_request:
|
pull_request:
|
||||||
@@ -13,33 +14,55 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm run install:all
|
run: npm run install:all
|
||||||
|
- name: Compile
|
||||||
- name: Compile TypeScript
|
|
||||||
run: npm run compile
|
run: npm run compile
|
||||||
|
- name: Check types
|
||||||
|
run: npm run check-types
|
||||||
|
- name: Lint
|
||||||
|
run: npm run lint
|
||||||
|
|
||||||
unit-test:
|
unit-test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm run install:all
|
run: npm run install:all
|
||||||
|
|
||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: npm test
|
run: npm test
|
||||||
|
|
||||||
|
integration-test:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest] # macos-latest, windows-latest
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '18'
|
||||||
|
cache: 'npm'
|
||||||
|
- name: Create env.integration file
|
||||||
|
run: echo "OPENROUTER_API_KEY=${{ secrets.OPENROUTER_API_KEY }}" > .env.integration
|
||||||
|
- name: Check env.integration file
|
||||||
|
run: cat .env.integration
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm run install:all
|
||||||
|
- run: xvfb-run -a npm run test:integration
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
- run: npm run test:integration
|
||||||
|
if: runner.os != 'Linux'
|
||||||
|
|||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,5 +1,6 @@
|
|||||||
out
|
|
||||||
dist
|
dist
|
||||||
|
out
|
||||||
|
out-integration
|
||||||
node_modules
|
node_modules
|
||||||
coverage/
|
coverage/
|
||||||
|
|
||||||
@@ -18,3 +19,6 @@ roo-cline-*.vsix
|
|||||||
|
|
||||||
# Docs
|
# Docs
|
||||||
docs/_site/
|
docs/_site/
|
||||||
|
|
||||||
|
# Dotenv
|
||||||
|
.env.integration
|
||||||
|
|||||||
@@ -6,4 +6,7 @@ if [ "$branch" = "main" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
npx lint-staged
|
npx lint-staged
|
||||||
|
|
||||||
npm run compile
|
npm run compile
|
||||||
|
npm run lint
|
||||||
|
npm run check-types
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* See: https://code.visualstudio.com/api/working-with-extensions/testing-extension
|
||||||
|
*/
|
||||||
|
|
||||||
import { defineConfig } from '@vscode/test-cli';
|
import { defineConfig } from '@vscode/test-cli';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
files: 'src/test/extension.test.ts',
|
label: 'integrationTest',
|
||||||
|
files: 'out-integration/test/**/*.test.js',
|
||||||
workspaceFolder: '.',
|
workspaceFolder: '.',
|
||||||
mocha: {
|
mocha: {
|
||||||
|
ui: 'tdd',
|
||||||
timeout: 60000,
|
timeout: 60000,
|
||||||
ui: 'tdd'
|
|
||||||
},
|
},
|
||||||
launchArgs: [
|
launchArgs: [
|
||||||
'--enable-proposed-api=RooVeterinaryInc.roo-cline',
|
'--enable-proposed-api=RooVeterinaryInc.roo-cline',
|
||||||
|
|||||||
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1737569578,
|
||||||
|
"narHash": "sha256-6qY0pk2QmUtBT9Mywdvif0i/CLVgpCjMUn6g9vB+f3M=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "47addd76727f42d351590c905d9d1905ca895b82",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-24.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
33
flake.nix
Normal file
33
flake.nix
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
description = "Roo Code development environment";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, ... }: let
|
||||||
|
systems = [ "aarch64-darwin" "x86_64-linux" ];
|
||||||
|
|
||||||
|
forAllSystems = nixpkgs.lib.genAttrs systems;
|
||||||
|
|
||||||
|
mkDevShell = system: let
|
||||||
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
in pkgs.mkShell {
|
||||||
|
name = "roo-code";
|
||||||
|
|
||||||
|
packages = with pkgs; [
|
||||||
|
zsh
|
||||||
|
nodejs_18
|
||||||
|
corepack_18
|
||||||
|
];
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
exec zsh
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
devShells = forAllSystems (system: {
|
||||||
|
default = mkDevShell system;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
176
package-lock.json
generated
176
package-lock.json
generated
@@ -55,6 +55,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/cli": "^2.27.10",
|
"@changesets/cli": "^2.27.10",
|
||||||
"@changesets/types": "^6.0.0",
|
"@changesets/types": "^6.0.0",
|
||||||
|
"@dotenvx/dotenvx": "^1.34.0",
|
||||||
"@types/diff": "^5.2.1",
|
"@types/diff": "^5.2.1",
|
||||||
"@types/diff-match-patch": "^1.0.36",
|
"@types/diff-match-patch": "^1.0.36",
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
@@ -65,7 +66,6 @@
|
|||||||
"@typescript-eslint/parser": "^7.11.0",
|
"@typescript-eslint/parser": "^7.11.0",
|
||||||
"@vscode/test-cli": "^0.0.9",
|
"@vscode/test-cli": "^0.0.9",
|
||||||
"@vscode/test-electron": "^2.4.0",
|
"@vscode/test-electron": "^2.4.0",
|
||||||
"dotenv": "^16.4.7",
|
|
||||||
"esbuild": "^0.24.0",
|
"esbuild": "^0.24.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
@@ -3030,6 +3030,110 @@
|
|||||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@dotenvx/dotenvx": {
|
||||||
|
"version": "1.34.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.34.0.tgz",
|
||||||
|
"integrity": "sha512-+Dp/xaI3IZ4eKv+b2vg4V89VnqLKbmJ7UZ7unnZxMu9SNLOSc2jYaXey1YHCJM+67T0pOr2Gbej3TewnuoqTWQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"commander": "^11.1.0",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
|
"eciesjs": "^0.4.10",
|
||||||
|
"execa": "^5.1.1",
|
||||||
|
"fdir": "^6.2.0",
|
||||||
|
"ignore": "^5.3.0",
|
||||||
|
"object-treeify": "1.1.33",
|
||||||
|
"picomatch": "^4.0.2",
|
||||||
|
"which": "^4.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"dotenvx": "src/cli/dotenvx.js",
|
||||||
|
"git-dotenvx": "src/cli/dotenvx.js"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://dotenvx.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@dotenvx/dotenvx/node_modules/commander": {
|
||||||
|
"version": "11.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
|
||||||
|
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@dotenvx/dotenvx/node_modules/fdir": {
|
||||||
|
"version": "6.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
|
||||||
|
"integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"picomatch": "^3 || ^4"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"picomatch": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@dotenvx/dotenvx/node_modules/isexe": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@dotenvx/dotenvx/node_modules/picomatch": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@dotenvx/dotenvx/node_modules/which": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"isexe": "^3.1.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"node-which": "bin/which.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^16.13.0 || >=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@ecies/ciphers": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ecies/ciphers/-/ciphers-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-ylfGR7PyTd+Rm2PqQowG08BCKA22QuX8NzrL+LxAAvazN10DMwdJ2fWwAzRj05FI/M8vNFGm3cv9Wq/GFWCBLg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"bun": ">=1",
|
||||||
|
"deno": ">=2",
|
||||||
|
"node": ">=16"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@noble/ciphers": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@esbuild/darwin-arm64": {
|
"node_modules/@esbuild/darwin-arm64": {
|
||||||
"version": "0.24.0",
|
"version": "0.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz",
|
||||||
@@ -3964,6 +4068,48 @@
|
|||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@noble/ciphers": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.21.3 || >=16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@noble/curves": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.1.tgz",
|
||||||
|
"integrity": "sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@noble/hashes": "1.7.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.21.3 || >=16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@noble/hashes": {
|
||||||
|
"version": "1.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz",
|
||||||
|
"integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.21.3 || >=16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
"version": "2.1.5",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||||
@@ -7772,6 +7918,24 @@
|
|||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eciesjs": {
|
||||||
|
"version": "0.4.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.4.13.tgz",
|
||||||
|
"integrity": "sha512-zBdtR4K+wbj10bWPpIOF9DW+eFYQu8miU5ypunh0t4Bvt83ZPlEWgT5Dq/0G6uwEXumZKjfb5BZxYUZQ2Hzn/Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ecies/ciphers": "^0.2.2",
|
||||||
|
"@noble/ciphers": "^1.0.0",
|
||||||
|
"@noble/curves": "^1.6.0",
|
||||||
|
"@noble/hashes": "^1.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"bun": ">=1",
|
||||||
|
"deno": ">=2",
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eight-colors": {
|
"node_modules/eight-colors": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/eight-colors/-/eight-colors-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/eight-colors/-/eight-colors-1.3.1.tgz",
|
||||||
@@ -12247,6 +12411,16 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/object-treeify": {
|
||||||
|
"version": "1.1.33",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz",
|
||||||
|
"integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object.assign": {
|
"node_modules/object.assign": {
|
||||||
"version": "4.1.5",
|
"version": "4.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -221,16 +221,16 @@
|
|||||||
"build:webview": "cd webview-ui && npm run build",
|
"build:webview": "cd webview-ui && npm run build",
|
||||||
"changeset": "changeset",
|
"changeset": "changeset",
|
||||||
"check-types": "tsc --noEmit",
|
"check-types": "tsc --noEmit",
|
||||||
"compile": "npm run check-types && npm run lint && node esbuild.js",
|
"compile": "tsc -p . --outDir out && node esbuild.js",
|
||||||
"compile-tests": "tsc -p . --outDir out",
|
"compile:integration": "tsc -p tsconfig.integration.json",
|
||||||
"install:all": "npm install && cd webview-ui && npm install",
|
"install:all": "npm install && cd webview-ui && npm install",
|
||||||
"lint": "eslint src --ext ts && npm run lint --prefix webview-ui",
|
"lint": "eslint src --ext ts && npm run lint --prefix webview-ui",
|
||||||
"package": "npm run build:webview && npm run check-types && npm run lint && node esbuild.js --production",
|
"package": "npm run build:webview && npm run check-types && npm run lint && node esbuild.js --production",
|
||||||
"pretest": "npm run compile-tests && npm run compile && npm run lint",
|
"pretest": "npm run compile && npm run compile:integration",
|
||||||
"dev": "cd webview-ui && npm run dev",
|
"dev": "cd webview-ui && npm run dev",
|
||||||
"test": "jest && npm run test:webview",
|
"test": "jest && npm run test:webview",
|
||||||
"test:webview": "cd webview-ui && npm run test",
|
"test:webview": "cd webview-ui && npm run test",
|
||||||
"test:extension": "vscode-test",
|
"test:integration": "npm run build && npm run compile:integration && npx dotenvx run -f .env.integration -- vscode-test",
|
||||||
"prepare": "husky",
|
"prepare": "husky",
|
||||||
"publish:marketplace": "vsce publish && ovsx publish",
|
"publish:marketplace": "vsce publish && ovsx publish",
|
||||||
"publish": "npm run build && changeset publish && npm install --package-lock-only",
|
"publish": "npm run build && changeset publish && npm install --package-lock-only",
|
||||||
@@ -245,6 +245,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@changesets/cli": "^2.27.10",
|
"@changesets/cli": "^2.27.10",
|
||||||
"@changesets/types": "^6.0.0",
|
"@changesets/types": "^6.0.0",
|
||||||
|
"@dotenvx/dotenvx": "^1.34.0",
|
||||||
"@types/diff": "^5.2.1",
|
"@types/diff": "^5.2.1",
|
||||||
"@types/diff-match-patch": "^1.0.36",
|
"@types/diff-match-patch": "^1.0.36",
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
@@ -255,7 +256,6 @@
|
|||||||
"@typescript-eslint/parser": "^7.11.0",
|
"@typescript-eslint/parser": "^7.11.0",
|
||||||
"@vscode/test-cli": "^0.0.9",
|
"@vscode/test-cli": "^0.0.9",
|
||||||
"@vscode/test-electron": "^2.4.0",
|
"@vscode/test-electron": "^2.4.0",
|
||||||
"dotenv": "^16.4.7",
|
|
||||||
"esbuild": "^0.24.0",
|
"esbuild": "^0.24.0",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
|
|||||||
@@ -19,15 +19,7 @@ import { findLast } from "../../shared/array"
|
|||||||
import { ApiConfigMeta, ExtensionMessage } from "../../shared/ExtensionMessage"
|
import { ApiConfigMeta, ExtensionMessage } from "../../shared/ExtensionMessage"
|
||||||
import { HistoryItem } from "../../shared/HistoryItem"
|
import { HistoryItem } from "../../shared/HistoryItem"
|
||||||
import { WebviewMessage } from "../../shared/WebviewMessage"
|
import { WebviewMessage } from "../../shared/WebviewMessage"
|
||||||
import {
|
import { Mode, CustomModePrompts, PromptComponent, defaultModeSlug } from "../../shared/modes"
|
||||||
Mode,
|
|
||||||
modes,
|
|
||||||
CustomModePrompts,
|
|
||||||
PromptComponent,
|
|
||||||
ModeConfig,
|
|
||||||
defaultModeSlug,
|
|
||||||
getModeBySlug,
|
|
||||||
} from "../../shared/modes"
|
|
||||||
import { SYSTEM_PROMPT } from "../prompts/system"
|
import { SYSTEM_PROMPT } from "../prompts/system"
|
||||||
import { fileExistsAtPath } from "../../utils/fs"
|
import { fileExistsAtPath } from "../../utils/fs"
|
||||||
import { Cline } from "../Cline"
|
import { Cline } from "../Cline"
|
||||||
@@ -37,7 +29,7 @@ import { getUri } from "./getUri"
|
|||||||
import { playSound, setSoundEnabled, setSoundVolume } from "../../utils/sound"
|
import { playSound, setSoundEnabled, setSoundVolume } from "../../utils/sound"
|
||||||
import { checkExistKey } from "../../shared/checkExistApiConfig"
|
import { checkExistKey } from "../../shared/checkExistApiConfig"
|
||||||
import { singleCompletionHandler } from "../../utils/single-completion-handler"
|
import { singleCompletionHandler } from "../../utils/single-completion-handler"
|
||||||
import { getCommitInfo, searchCommits, getWorkingState } from "../../utils/git"
|
import { searchCommits } from "../../utils/git"
|
||||||
import { ConfigManager } from "../config/ConfigManager"
|
import { ConfigManager } from "../config/ConfigManager"
|
||||||
import { CustomModesManager } from "../config/CustomModesManager"
|
import { CustomModesManager } from "../config/CustomModesManager"
|
||||||
import { EXPERIMENT_IDS, experiments as Experiments, experimentDefault, ExperimentId } from "../../shared/experiments"
|
import { EXPERIMENT_IDS, experiments as Experiments, experimentDefault, ExperimentId } from "../../shared/experiments"
|
||||||
@@ -140,6 +132,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||||||
private static activeInstances: Set<ClineProvider> = new Set()
|
private static activeInstances: Set<ClineProvider> = new Set()
|
||||||
private disposables: vscode.Disposable[] = []
|
private disposables: vscode.Disposable[] = []
|
||||||
private view?: vscode.WebviewView | vscode.WebviewPanel
|
private view?: vscode.WebviewView | vscode.WebviewPanel
|
||||||
|
private isViewLaunched = false
|
||||||
private cline?: Cline
|
private cline?: Cline
|
||||||
private workspaceTracker?: WorkspaceTracker
|
private workspaceTracker?: WorkspaceTracker
|
||||||
mcpHub?: McpHub
|
mcpHub?: McpHub
|
||||||
@@ -652,6 +645,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
this.isViewLaunched = true
|
||||||
break
|
break
|
||||||
case "newTask":
|
case "newTask":
|
||||||
// Code that should run in response to the hello message command
|
// Code that should run in response to the hello message command
|
||||||
@@ -2422,7 +2416,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||||||
|
|
||||||
// secrets
|
// secrets
|
||||||
|
|
||||||
private async storeSecret(key: SecretKey, value?: string) {
|
public async storeSecret(key: SecretKey, value?: string) {
|
||||||
if (value) {
|
if (value) {
|
||||||
await this.context.secrets.store(key, value)
|
await this.context.secrets.store(key, value)
|
||||||
} else {
|
} else {
|
||||||
@@ -2476,4 +2470,14 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||||||
await this.postStateToWebview()
|
await this.postStateToWebview()
|
||||||
await this.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
|
await this.postMessageToWebview({ type: "action", action: "chatButtonClicked" })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// integration tests
|
||||||
|
|
||||||
|
get viewLaunched() {
|
||||||
|
return this.isViewLaunched
|
||||||
|
}
|
||||||
|
|
||||||
|
get messages() {
|
||||||
|
return this.cline?.clineMessages || []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,121 +1,18 @@
|
|||||||
const assert = require("assert")
|
import * as assert from "assert"
|
||||||
const vscode = require("vscode")
|
import * as vscode from "vscode"
|
||||||
const path = require("path")
|
|
||||||
const fs = require("fs")
|
|
||||||
const dotenv = require("dotenv")
|
|
||||||
|
|
||||||
// Load test environment variables
|
suite("Roo Code Extension", () => {
|
||||||
const testEnvPath = path.join(__dirname, ".test_env")
|
test("OPENROUTER_API_KEY environment variable is set", () => {
|
||||||
dotenv.config({ path: testEnvPath })
|
if (!process.env.OPENROUTER_API_KEY) {
|
||||||
|
assert.fail("OPENROUTER_API_KEY environment variable is not set")
|
||||||
suite("Roo Code Extension Test Suite", () => {
|
|
||||||
vscode.window.showInformationMessage("Starting Roo Code extension tests.")
|
|
||||||
|
|
||||||
test("Extension should be present", () => {
|
|
||||||
const extension = vscode.extensions.getExtension("RooVeterinaryInc.roo-cline")
|
|
||||||
assert.notStrictEqual(extension, undefined)
|
|
||||||
})
|
|
||||||
|
|
||||||
test("Extension should activate", async () => {
|
|
||||||
const extension = vscode.extensions.getExtension("RooVeterinaryInc.roo-cline")
|
|
||||||
if (!extension) {
|
|
||||||
assert.fail("Extension not found")
|
|
||||||
}
|
}
|
||||||
await extension.activate()
|
|
||||||
assert.strictEqual(extension.isActive, true)
|
|
||||||
})
|
|
||||||
|
|
||||||
test("OpenRouter API key and models should be configured correctly", function (done) {
|
|
||||||
// @ts-ignore
|
|
||||||
this.timeout(60000) // Increase timeout to 60s for network requests
|
|
||||||
;(async () => {
|
|
||||||
try {
|
|
||||||
// Get extension instance
|
|
||||||
const extension = vscode.extensions.getExtension("RooVeterinaryInc.roo-cline")
|
|
||||||
if (!extension) {
|
|
||||||
done(new Error("Extension not found"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify API key is set and valid
|
|
||||||
const apiKey = process.env.OPEN_ROUTER_API_KEY
|
|
||||||
if (!apiKey) {
|
|
||||||
done(new Error("OPEN_ROUTER_API_KEY environment variable is not set"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!apiKey.startsWith("sk-or-v1-")) {
|
|
||||||
done(new Error("OpenRouter API key should have correct format"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Activate extension and get provider
|
|
||||||
const api = await extension.activate()
|
|
||||||
if (!api) {
|
|
||||||
done(new Error("Extension API not found"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the provider from the extension's exports
|
|
||||||
const provider = api.sidebarProvider
|
|
||||||
if (!provider) {
|
|
||||||
done(new Error("Provider not found"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up the API configuration
|
|
||||||
await provider.updateGlobalState("apiProvider", "openrouter")
|
|
||||||
await provider.storeSecret("openRouterApiKey", apiKey)
|
|
||||||
|
|
||||||
// Set up timeout to fail test if models don't load
|
|
||||||
const timeout = setTimeout(() => {
|
|
||||||
done(new Error("Timeout waiting for models to load"))
|
|
||||||
}, 30000)
|
|
||||||
|
|
||||||
// Wait for models to be loaded
|
|
||||||
const checkModels = setInterval(async () => {
|
|
||||||
try {
|
|
||||||
const models = await provider.readOpenRouterModels()
|
|
||||||
if (!models) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
clearInterval(checkModels)
|
|
||||||
clearTimeout(timeout)
|
|
||||||
|
|
||||||
// Verify expected Claude models are available
|
|
||||||
const expectedModels = [
|
|
||||||
"anthropic/claude-3.5-sonnet:beta",
|
|
||||||
"anthropic/claude-3-sonnet:beta",
|
|
||||||
"anthropic/claude-3.5-sonnet",
|
|
||||||
"anthropic/claude-3.5-sonnet-20240620",
|
|
||||||
"anthropic/claude-3.5-sonnet-20240620:beta",
|
|
||||||
"anthropic/claude-3.5-haiku:beta",
|
|
||||||
]
|
|
||||||
|
|
||||||
for (const modelId of expectedModels) {
|
|
||||||
assert.strictEqual(modelId in models, true, `Model ${modelId} should be available`)
|
|
||||||
}
|
|
||||||
|
|
||||||
done()
|
|
||||||
} catch (error) {
|
|
||||||
clearInterval(checkModels)
|
|
||||||
clearTimeout(timeout)
|
|
||||||
done(error)
|
|
||||||
}
|
|
||||||
}, 1000)
|
|
||||||
|
|
||||||
// Trigger model loading
|
|
||||||
await provider.refreshOpenRouterModels()
|
|
||||||
} catch (error) {
|
|
||||||
done(error)
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test("Commands should be registered", async () => {
|
test("Commands should be registered", async () => {
|
||||||
const commands = await vscode.commands.getCommands(true)
|
const timeout = 10 * 1_000
|
||||||
|
const interval = 1_000
|
||||||
|
const startTime = Date.now()
|
||||||
|
|
||||||
// Test core commands are registered
|
|
||||||
const expectedCommands = [
|
const expectedCommands = [
|
||||||
"roo-cline.plusButtonClicked",
|
"roo-cline.plusButtonClicked",
|
||||||
"roo-cline.mcpButtonClicked",
|
"roo-cline.mcpButtonClicked",
|
||||||
@@ -128,204 +25,39 @@ suite("Roo Code Extension Test Suite", () => {
|
|||||||
"roo-cline.improveCode",
|
"roo-cline.improveCode",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
while (Date.now() - startTime < timeout) {
|
||||||
|
const commands = await vscode.commands.getCommands(true)
|
||||||
|
const missingCommands = []
|
||||||
|
|
||||||
for (const cmd of expectedCommands) {
|
for (const cmd of expectedCommands) {
|
||||||
assert.strictEqual(commands.includes(cmd), true, `Command ${cmd} should be registered`)
|
if (!commands.includes(cmd)) {
|
||||||
|
missingCommands.push(cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (missingCommands.length === 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, interval))
|
||||||
|
}
|
||||||
|
|
||||||
|
const commands = await vscode.commands.getCommands(true)
|
||||||
|
|
||||||
|
for (const cmd of expectedCommands) {
|
||||||
|
assert.ok(commands.includes(cmd), `Command ${cmd} should be registered`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
test("Views should be registered", () => {
|
test("Webview panel can be created", () => {
|
||||||
const view = vscode.window.createWebviewPanel(
|
const view = vscode.window.createWebviewPanel(
|
||||||
"roo-cline.SidebarProvider",
|
"roo-cline.SidebarProvider",
|
||||||
"Roo Code",
|
"Roo Code",
|
||||||
vscode.ViewColumn.One,
|
vscode.ViewColumn.One,
|
||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
assert.notStrictEqual(view, undefined)
|
|
||||||
|
assert.ok(view, "Failed to create webview panel")
|
||||||
view.dispose()
|
view.dispose()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("Should handle prompt and response correctly", async function () {
|
|
||||||
// @ts-ignore
|
|
||||||
this.timeout(60000) // Increase timeout for API request
|
|
||||||
|
|
||||||
const timeout = 30000
|
|
||||||
const interval = 1000
|
|
||||||
|
|
||||||
// Get extension instance
|
|
||||||
const extension = vscode.extensions.getExtension("RooVeterinaryInc.roo-cline")
|
|
||||||
if (!extension) {
|
|
||||||
assert.fail("Extension not found")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Activate extension and get API
|
|
||||||
const api = await extension.activate()
|
|
||||||
if (!api) {
|
|
||||||
assert.fail("Extension API not found")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get provider
|
|
||||||
const provider = api.sidebarProvider
|
|
||||||
if (!provider) {
|
|
||||||
assert.fail("Provider not found")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up API configuration
|
|
||||||
await provider.updateGlobalState("apiProvider", "openrouter")
|
|
||||||
await provider.updateGlobalState("openRouterModelId", "anthropic/claude-3.5-sonnet")
|
|
||||||
const apiKey = process.env.OPEN_ROUTER_API_KEY
|
|
||||||
if (!apiKey) {
|
|
||||||
assert.fail("OPEN_ROUTER_API_KEY environment variable is not set")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
await provider.storeSecret("openRouterApiKey", apiKey)
|
|
||||||
|
|
||||||
// Create webview panel with development options
|
|
||||||
const extensionUri = extension.extensionUri
|
|
||||||
const panel = vscode.window.createWebviewPanel("roo-cline.SidebarProvider", "Roo Code", vscode.ViewColumn.One, {
|
|
||||||
enableScripts: true,
|
|
||||||
enableCommandUris: true,
|
|
||||||
retainContextWhenHidden: true,
|
|
||||||
localResourceRoots: [extensionUri],
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Initialize webview with development context
|
|
||||||
panel.webview.options = {
|
|
||||||
enableScripts: true,
|
|
||||||
enableCommandUris: true,
|
|
||||||
localResourceRoots: [extensionUri],
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize provider with panel
|
|
||||||
provider.resolveWebviewView(panel)
|
|
||||||
|
|
||||||
// Set up message tracking
|
|
||||||
let webviewReady = false
|
|
||||||
let messagesReceived = false
|
|
||||||
const originalPostMessage = provider.postMessageToWebview.bind(provider)
|
|
||||||
// @ts-ignore
|
|
||||||
provider.postMessageToWebview = async (message) => {
|
|
||||||
if (message.type === "state") {
|
|
||||||
webviewReady = true
|
|
||||||
console.log("Webview state received:", message)
|
|
||||||
if (message.state?.clineMessages?.length > 0) {
|
|
||||||
messagesReceived = true
|
|
||||||
console.log("Messages in state:", message.state.clineMessages)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await originalPostMessage(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for webview to launch and receive initial state
|
|
||||||
let startTime = Date.now()
|
|
||||||
while (Date.now() - startTime < timeout) {
|
|
||||||
if (webviewReady) {
|
|
||||||
// Wait an additional second for webview to fully initialize
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, interval))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!webviewReady) {
|
|
||||||
throw new Error("Timeout waiting for webview to be ready")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send webviewDidLaunch to initialize chat
|
|
||||||
await provider.postMessageToWebview({ type: "webviewDidLaunch" })
|
|
||||||
console.log("Sent webviewDidLaunch")
|
|
||||||
|
|
||||||
// Wait for webview to fully initialize
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 2000))
|
|
||||||
|
|
||||||
// Restore original postMessage
|
|
||||||
provider.postMessageToWebview = originalPostMessage
|
|
||||||
|
|
||||||
// Wait for OpenRouter models to be fully loaded
|
|
||||||
startTime = Date.now()
|
|
||||||
while (Date.now() - startTime < timeout) {
|
|
||||||
const models = await provider.readOpenRouterModels()
|
|
||||||
if (models && Object.keys(models).length > 0) {
|
|
||||||
console.log("OpenRouter models loaded")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, interval))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send prompt
|
|
||||||
const prompt = "Hello world, what is your name?"
|
|
||||||
console.log("Sending prompt:", prompt)
|
|
||||||
|
|
||||||
// Start task
|
|
||||||
try {
|
|
||||||
await api.startNewTask(prompt)
|
|
||||||
console.log("Task started")
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error starting task:", error)
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for task to appear in history with tokens
|
|
||||||
startTime = Date.now()
|
|
||||||
while (Date.now() - startTime < timeout) {
|
|
||||||
const state = await provider.getState()
|
|
||||||
const task = state.taskHistory?.[0]
|
|
||||||
if (task && task.tokensOut > 0) {
|
|
||||||
console.log("Task completed with tokens:", task)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, interval))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for messages to be processed
|
|
||||||
startTime = Date.now()
|
|
||||||
let responseReceived = false
|
|
||||||
while (Date.now() - startTime < timeout) {
|
|
||||||
// Check provider.clineMessages
|
|
||||||
const messages = provider.clineMessages
|
|
||||||
if (messages && messages.length > 0) {
|
|
||||||
console.log("Provider messages:", JSON.stringify(messages, null, 2))
|
|
||||||
// @ts-ignore
|
|
||||||
const hasResponse = messages.some(
|
|
||||||
(m: { type: string; text: string }) =>
|
|
||||||
m.type === "say" && m.text && m.text.toLowerCase().includes("cline"),
|
|
||||||
)
|
|
||||||
if (hasResponse) {
|
|
||||||
console.log('Found response containing "Cline" in provider messages')
|
|
||||||
responseReceived = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check provider.cline.clineMessages
|
|
||||||
const clineMessages = provider.cline?.clineMessages
|
|
||||||
if (clineMessages && clineMessages.length > 0) {
|
|
||||||
console.log("Cline messages:", JSON.stringify(clineMessages, null, 2))
|
|
||||||
// @ts-ignore
|
|
||||||
const hasResponse = clineMessages.some(
|
|
||||||
(m: { type: string; text: string }) =>
|
|
||||||
m.type === "say" && m.text && m.text.toLowerCase().includes("cline"),
|
|
||||||
)
|
|
||||||
if (hasResponse) {
|
|
||||||
console.log('Found response containing "Cline" in cline messages')
|
|
||||||
responseReceived = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, interval))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!responseReceived) {
|
|
||||||
console.log("Final provider state:", await provider.getState())
|
|
||||||
console.log("Final cline messages:", provider.cline?.clineMessages)
|
|
||||||
throw new Error('Did not receive expected response containing "Cline"')
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
panel.dispose()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
77
src/test/task.test.ts
Normal file
77
src/test/task.test.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import * as assert from "assert"
|
||||||
|
import * as vscode from "vscode"
|
||||||
|
|
||||||
|
import { ClineAPI } from "../exports/cline"
|
||||||
|
import { ClineProvider } from "../core/webview/ClineProvider"
|
||||||
|
|
||||||
|
suite("Roo Code Task", () => {
|
||||||
|
test("Should handle prompt and response correctly", async function () {
|
||||||
|
const timeout = 30000
|
||||||
|
const interval = 1000
|
||||||
|
|
||||||
|
const extension = vscode.extensions.getExtension("RooVeterinaryInc.roo-cline")
|
||||||
|
|
||||||
|
if (!extension) {
|
||||||
|
assert.fail("Extension not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
const api: ClineAPI = await extension.activate()
|
||||||
|
const provider = api.sidebarProvider as ClineProvider
|
||||||
|
await provider.updateGlobalState("apiProvider", "openrouter")
|
||||||
|
await provider.updateGlobalState("openRouterModelId", "anthropic/claude-3.5-sonnet")
|
||||||
|
await provider.storeSecret("openRouterApiKey", process.env.OPENROUTER_API_KEY || "sk-or-v1-fake-api-key")
|
||||||
|
|
||||||
|
// Create webview panel with development options.
|
||||||
|
const panel = vscode.window.createWebviewPanel("roo-cline.SidebarProvider", "Roo Code", vscode.ViewColumn.One, {
|
||||||
|
enableScripts: true,
|
||||||
|
enableCommandUris: true,
|
||||||
|
retainContextWhenHidden: true,
|
||||||
|
localResourceRoots: [extension.extensionUri],
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Initialize provider with panel.
|
||||||
|
provider.resolveWebviewView(panel)
|
||||||
|
|
||||||
|
// Wait for webview to launch.
|
||||||
|
let startTime = Date.now()
|
||||||
|
|
||||||
|
while (Date.now() - startTime < timeout) {
|
||||||
|
if (provider.viewLaunched) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, interval))
|
||||||
|
}
|
||||||
|
|
||||||
|
await api.startNewTask("Hello world, what is your name? Respond with 'My name is ...'")
|
||||||
|
|
||||||
|
// Wait for task to appear in history with tokens.
|
||||||
|
startTime = Date.now()
|
||||||
|
|
||||||
|
while (Date.now() - startTime < timeout) {
|
||||||
|
const state = await provider.getState()
|
||||||
|
const task = state.taskHistory?.[0]
|
||||||
|
|
||||||
|
if (task && task.tokensOut > 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, interval))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (provider.messages.length === 0) {
|
||||||
|
assert.fail("No messages received")
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log("Provider messages:", JSON.stringify(provider.messages, null, 2))
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
provider.messages.some(({ type, text }) => type === "say" && text?.includes("My name is Roo")),
|
||||||
|
"Did not receive expected response containing 'My name is Roo'",
|
||||||
|
)
|
||||||
|
} finally {
|
||||||
|
panel.dispose()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "ES2020",
|
|
||||||
"lib": ["ES2020"],
|
|
||||||
"sourceMap": true,
|
|
||||||
"rootDir": "../..",
|
|
||||||
"strict": false,
|
|
||||||
"noImplicitAny": false,
|
|
||||||
"noImplicitThis": false,
|
|
||||||
"alwaysStrict": false,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"baseUrl": "../..",
|
|
||||||
"paths": {
|
|
||||||
"*": ["*", "src/*"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"exclude": ["node_modules", ".vscode-test"]
|
|
||||||
}
|
|
||||||
17
tsconfig.integration.json
Normal file
17
tsconfig.integration.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "CommonJS",
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"target": "ES2022",
|
||||||
|
"lib": ["ES2022", "ESNext.Disposable", "DOM"],
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"useUnknownInCatchVariables": false,
|
||||||
|
"rootDir": "src",
|
||||||
|
"outDir": "out-integration"
|
||||||
|
},
|
||||||
|
"include": ["**/*.ts"],
|
||||||
|
"exclude": [".vscode-test", "benchmark", "dist", "**/node_modules/**", "out", "out-integration", "webview-ui"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user