From 7809d458aaeb9fb706996faeb8d5f737dea1deff Mon Sep 17 00:00:00 2001 From: yaoweiprc <6896642+yaoweiprc@users.noreply.github.com> Date: Thu, 30 Apr 2026 21:16:18 +0800 Subject: [PATCH] Update E2E test for git sync [INS-2258] (#9878) * Add more test cases for git sync * tmp * Update package.json --- package-lock.json | 457 +----------------- packages/insomnia-smoke-test/package.json | 2 +- .../insomnia-smoke-test/playwright.config.ts | 2 +- packages/insomnia-smoke-test/server/index.ts | 70 ++- .../tests/smoke/git-sync.test.ts | 99 +++- .../modals/git-project-staging-modal.tsx | 1 + 6 files changed, 162 insertions(+), 469 deletions(-) diff --git a/package-lock.json b/package-lock.json index a3a50ca839..22d0098412 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11591,29 +11591,6 @@ "dev": true, "license": "MIT" }, - "node_modules/apache-crypt": { - "version": "1.2.6", - "resolved": "https://registry.npmmirror.com/apache-crypt/-/apache-crypt-1.2.6.tgz", - "integrity": "sha512-072WetlM4blL8PREJVeY+WHiUh1R5VNt2HfceGS8aKqttPHcmqE5pkKuXPz/ULmJOFkc8Hw3kfKl6vy7Qka6DA==", - "dev": true, - "license": "MIT", - "dependencies": { - "unix-crypt-td-js": "^1.1.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/apache-md5": { - "version": "1.1.8", - "resolved": "https://registry.npmmirror.com/apache-md5/-/apache-md5-1.1.8.tgz", - "integrity": "sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/apiconnect-wsdl": { "version": "2.0.36", "resolved": "https://registry.npmjs.org/apiconnect-wsdl/-/apiconnect-wsdl-2.0.36.tgz", @@ -11941,29 +11918,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array.prototype.findlast": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", @@ -12067,16 +12021,6 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "license": "MIT" }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmmirror.com/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -12297,13 +12241,6 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, - "node_modules/bcryptjs": { - "version": "2.4.3", - "resolved": "https://registry.npmmirror.com/bcryptjs/-/bcryptjs-2.4.3.tgz", - "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", - "dev": true, - "license": "MIT" - }, "node_modules/bignumber.js": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", @@ -13755,16 +13692,6 @@ "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", "license": "MIT" }, - "node_modules/crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/css-in-js-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", @@ -13876,16 +13803,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/daemonize-process": { - "version": "1.0.9", - "resolved": "https://registry.npmmirror.com/daemonize-process/-/daemonize-process-1.0.9.tgz", - "integrity": "sha512-YoB+AmcgHIBDVeyfVWSCV90FNk799zX8Uvn7RJTDCD8Y0EMNbSfIKLG961VgchJme2GHmqpXUuV8Rxe2j2L+bw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4" - } - }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -14591,19 +14508,6 @@ "node": "*" } }, - "node_modules/dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/dmg-builder": { "version": "26.8.1", "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.8.1.tgz", @@ -17032,31 +16936,6 @@ "micromatch": "^4.0.2" } }, - "node_modules/fixturez": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/fixturez/-/fixturez-1.1.0.tgz", - "integrity": "sha512-c4q9eZsAmCzj9gkrEO/YwIRlrHWt/TXQiX9jR9WeLFOqeeV6EyzdiiV28CpSzF6Ip+gyYrSv5UeOHqyzfcNTVA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fs-extra": "^5.0.0", - "globby": "^7.1.1", - "signal-exit": "^3.0.2", - "tempy": "^0.2.1" - } - }, - "node_modules/fixturez/node_modules/fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -17496,107 +17375,23 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/git-http-mock-server": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/git-http-mock-server/-/git-http-mock-server-2.0.0.tgz", - "integrity": "sha512-LOCls7jjuzwfKmUbcFsqj2yIEqExBzv0rA1tL7j1ULhRLAax4U1Bd/rbU9ebtri1ldzgcPD1VAyuhS1pvDC2pA==", + "node_modules/git-http-backend": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/git-http-backend/-/git-http-backend-1.1.2.tgz", + "integrity": "sha512-Gx7n/kyCEXGFZlCGmbsEsyeyabLs8XWeb+E/6842up7p3PktQS2/8rlNfB6hCagnW0pJ13Tn8E3yhOkKS6ihdg==", "dev": true, "license": "MIT", "dependencies": { - "basic-auth": "^2.0.0", - "buffer-equal-constant-time": "^1.0.1", - "chalk": "^2.4.1", - "daemonize-process": "^1.0.9", - "fixturez": "^1.1.0", - "htpasswd-js": "^1.0.2", - "micro-cors": "^0.1.1", - "minimisted": "^2.0.0", - "ssh-keygen": "^0.4.2", - "ssh2": "^0.6.1", - "tree-kill": "^1.2.0" - }, - "bin": { - "git-http-mock-server": "http-daemon.js", - "git-ssh-mock-server": "ssh-daemon.js" + "git-side-band-message": "~0.0.3", + "inherits": "~2.0.1" } }, - "node_modules/git-http-mock-server/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/git-side-band-message": { + "version": "0.0.3", + "resolved": "https://registry.npmmirror.com/git-side-band-message/-/git-side-band-message-0.0.3.tgz", + "integrity": "sha512-4Rq4xm1+zqCkmuHxRbGdA5ActF7F4UfgK8uI0B7ZfSkByZfikRuF7mqHlvqmycvqos7jpXNkgsZK7DThLLHG3w==", "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/git-http-mock-server/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/git-http-mock-server/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/git-http-mock-server/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/git-http-mock-server/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/git-http-mock-server/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/git-http-mock-server/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } + "license": "BSD" }, "node_modules/glob": { "version": "7.2.3", @@ -17708,51 +17503,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globby": { - "version": "7.1.1", - "resolved": "https://registry.npmmirror.com/globby/-/globby-7.1.1.tgz", - "integrity": "sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/globby/node_modules/ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmmirror.com/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true, - "license": "MIT" - }, - "node_modules/globby/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/globby/node_modules/slash": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/slash/-/slash-1.0.0.tgz", - "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/gonzales-pe": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", @@ -18301,32 +18051,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/htpasswd-js": { - "version": "1.0.2", - "resolved": "https://registry.npmmirror.com/htpasswd-js/-/htpasswd-js-1.0.2.tgz", - "integrity": "sha512-KON5L4YKYXk647tmVclKgmHHG5nApjy9K+WiRoScnoWhS63lMoTca1ommUW2XQ3FDW8TtNDIQA7J0WYXICbMAA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "apache-crypt": "^1.2.1", - "apache-md5": "^1.1.2", - "bcryptjs": "^2.4.3", - "fs-extra": "^4.0.2", - "xerror": "^1.1.2" - } - }, - "node_modules/htpasswd-js/node_modules/fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, "node_modules/http-assert": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", @@ -21253,16 +20977,6 @@ "node": ">= 0.6" } }, - "node_modules/micro-cors": { - "version": "0.1.1", - "resolved": "https://registry.npmmirror.com/micro-cors/-/micro-cors-0.1.1.tgz", - "integrity": "sha512-6WqIahA5sbQR1Gjexp1VuWGFDKbZZleJb/gy1khNGk18a6iN1FdTcr3Q8twaxkV5H94RjxIBjirYbWCehpMBFw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -23658,29 +23372,6 @@ "dev": true, "license": "MIT" }, - "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-type/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -26306,60 +25997,6 @@ "license": "BSD-3-Clause", "optional": true }, - "node_modules/ssh-keygen": { - "version": "0.4.2", - "resolved": "https://registry.npmmirror.com/ssh-keygen/-/ssh-keygen-0.4.2.tgz", - "integrity": "sha512-SlEWW3cCtz87jwtCTfxo+tR+SQd4jJXWaBI/D9JVd74b2/N9ZvrWcd9lMFwFv0iMYb4aVAeMderH4AK5ZyW+Nw==", - "dev": true, - "dependencies": { - "underscore": "1.4.x" - }, - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/ssh-keygen/node_modules/underscore": { - "version": "1.4.4", - "resolved": "https://registry.npmmirror.com/underscore/-/underscore-1.4.4.tgz", - "integrity": "sha512-ZqGrAgaqqZM7LGRzNjLnw5elevWb5M8LEoDMadxIW3OWbcv72wMMgKdwOKpd5Fqxe8choLD8HN3iSj3TUh/giQ==", - "dev": true - }, - "node_modules/ssh2": { - "version": "0.6.2", - "resolved": "https://registry.npmmirror.com/ssh2/-/ssh2-0.6.2.tgz", - "integrity": "sha512-DJ+dOhXEEsmNpcQTI0x69FS++JH6qqL/ltEHf01pI1SSLMAcmD+hL4jRwvHjPwynPsmSUbHJ/WIZYzROfqZWjA==", - "dev": true, - "dependencies": { - "ssh2-streams": "~0.2.0" - }, - "engines": { - "node": ">=4.5.0" - } - }, - "node_modules/ssh2-streams": { - "version": "0.2.1", - "resolved": "https://registry.npmmirror.com/ssh2-streams/-/ssh2-streams-0.2.1.tgz", - "integrity": "sha512-3zCOsmunh1JWgPshfhKmBCL3lUtHPoh+a/cyQ49Ft0Q0aF7xgN06b76L+oKtFi0fgO57FLjFztb1GlJcEZ4a3Q==", - "dev": true, - "dependencies": { - "asn1": "~0.2.0", - "semver": "^5.1.0", - "streamsearch": "~0.1.2" - }, - "engines": { - "node": ">=4.5.0" - } - }, - "node_modules/ssh2-streams/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/ssri": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", @@ -26609,15 +26246,6 @@ "any-promise": "^1.1.0" } }, - "node_modules/streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmmirror.com/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -27225,16 +26853,6 @@ "node": ">=6.0.0" } }, - "node_modules/temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/temp-file": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", @@ -27298,20 +26916,6 @@ "rimraf": "bin.js" } }, - "node_modules/tempy": { - "version": "0.2.1", - "resolved": "https://registry.npmmirror.com/tempy/-/tempy-0.2.1.tgz", - "integrity": "sha512-LB83o9bfZGrntdqPuRdanIVCPReam9SOZKW0fOy5I9X3A854GGWi0tjCqoXEk84XIEYBc/x9Hq3EFop/H5wJaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "temp-dir": "^1.0.0", - "unique-string": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/throttle-debounce": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", @@ -27535,16 +27139,6 @@ "node": ">=18" } }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmmirror.com/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "license": "MIT", - "bin": { - "tree-kill": "cli.js" - } - }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", @@ -27951,19 +27545,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "crypto-random-string": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -27974,13 +27555,6 @@ "node": ">= 4.0.0" } }, - "node_modules/unix-crypt-td-js": { - "version": "1.1.4", - "resolved": "https://registry.npmmirror.com/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", - "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -29296,13 +28870,6 @@ } } }, - "node_modules/xerror": { - "version": "1.1.3", - "resolved": "https://registry.npmmirror.com/xerror/-/xerror-1.1.3.tgz", - "integrity": "sha512-2l5hmDymDUIuKT53v/nYxofTMUDQuu5P/Y3qHOjQiih6QUHBCgWpbpL3I8BoE5TVfUVTMmUQ0jdUAimTGc9UIg==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/xml-name-validator": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", @@ -29886,7 +29453,7 @@ "esbuild-runner": "2.2.2", "express": "^4.21.2", "express-basic-auth": "^1.2.1", - "git-http-mock-server": "^2.0.0", + "git-http-backend": "^1.1.2", "graphql": "^16.10.0", "graphql-http": "^1.22.4", "http-errors": "^2.0.0", diff --git a/packages/insomnia-smoke-test/package.json b/packages/insomnia-smoke-test/package.json index 7287d84950..43aa9c6aca 100644 --- a/packages/insomnia-smoke-test/package.json +++ b/packages/insomnia-smoke-test/package.json @@ -30,7 +30,7 @@ "esbuild-runner": "2.2.2", "express": "^4.21.2", "express-basic-auth": "^1.2.1", - "git-http-mock-server": "^2.0.0", + "git-http-backend": "^1.1.2", "graphql": "^16.10.0", "graphql-http": "^1.22.4", "http-errors": "^2.0.0", diff --git a/packages/insomnia-smoke-test/playwright.config.ts b/packages/insomnia-smoke-test/playwright.config.ts index 8309bd93bb..a8531d1ddb 100644 --- a/packages/insomnia-smoke-test/playwright.config.ts +++ b/packages/insomnia-smoke-test/playwright.config.ts @@ -19,7 +19,7 @@ const viteServer: PlaywrightTestConfig['webServer'] = { cwd: '../../', command: 'npm run watch:app', url: 'http://localhost:3334', - timeout: 15 * 1000, + timeout: 120 * 1000, reuseExistingServer: !process.env.CI, stdout: 'pipe', stderr: 'pipe', diff --git a/packages/insomnia-smoke-test/server/index.ts b/packages/insomnia-smoke-test/server/index.ts index 649160830d..f814c56017 100644 --- a/packages/insomnia-smoke-test/server/index.ts +++ b/packages/insomnia-smoke-test/server/index.ts @@ -1,14 +1,28 @@ +import { spawn } from 'node:child_process'; import crypto from 'node:crypto'; -import { readFileSync } from 'node:fs'; +import { cpSync, existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs'; import { createServer } from 'node:https'; +import { tmpdir } from 'node:os'; import nodePath from 'node:path'; +import type { Duplex } from 'node:stream'; import * as bodyParser from 'body-parser'; import cookieParser from 'cookie-parser'; import express from 'express'; -import gitMiddleware from 'git-http-mock-server/middleware'; import { createHandler } from 'graphql-http/lib/use/http'; +interface GitBackendService { + type: string; + cmd: string; + args: string[]; + createStream(): Duplex; +} +// git-http-backend has no @types package; require+cast is the standard workaround +const backend = require('git-http-backend') as ( + url: string, + cb: (err: Error | null, service: GitBackendService) => void, +) => NodeJS.ReadWriteStream; + import { basicAuthRouter } from './basic-auth'; import cloudSyncApi from './cloud-sync-api'; import githubApi from './github-api'; @@ -153,14 +167,50 @@ app.get('/v1/oauth/azure/config', (_req, res) => { }); }); -app.use( - '/git', - gitMiddleware({ - root: nodePath.join(__dirname, '../fixtures/git-repo'), - glob: '*', - route: '/', - }), -); +const GIT_FIXTURE_ROOT = nodePath.join(__dirname, '../fixtures/git-repo'); +let currentGitTmpDir: string | null = null; + +// Create a fresh per-test copy of the git fixture repo +app.post('/v1/test-utils/git/setup', (_req, res) => { + if (currentGitTmpDir && existsSync(currentGitTmpDir)) { + rmSync(currentGitTmpDir, { recursive: true, force: true }); + } + currentGitTmpDir = mkdtempSync(nodePath.join(tmpdir(), 'insomnia-git-')); + cpSync(GIT_FIXTURE_ROOT, currentGitTmpDir, { recursive: true }); + res.json({ success: true }); +}); + +// Remove the per-test copy +app.delete('/v1/test-utils/git/setup', (_req, res) => { + if (currentGitTmpDir && existsSync(currentGitTmpDir)) { + rmSync(currentGitTmpDir, { recursive: true, force: true }); + } + currentGitTmpDir = null; + res.json({ success: true }); +}); + +// Git smart HTTP server backed by git-http-backend — accepts real pushes. +// Falls back to the fixture root if no per-test dir is set up. +app.use('/git', (req, res) => { + const root = currentGitTmpDir ?? GIT_FIXTURE_ROOT; + // req.url has the '/git' prefix stripped by Express, e.g. '/git-server.git/info/refs?...' + const repoPath = nodePath.join(root, req.url.split('?')[0].split('/')[1]); + + req.pipe( + backend(req.url, (err, service) => { + if (err) { + res.status(500).end(err.message); + return; + } + res.setHeader('content-type', service.type); + const ps = spawn(service.cmd, service.args.concat(repoPath), { + env: { ...process.env, GIT_HTTP_EXPORT_ALL: '1' }, + }); + ps.stderr.on('data', d => console.error('[git]', String(d))); + ps.stdout.pipe(service.createStream()).pipe(ps.stdin); + }), + ).pipe(res); +}); startWebSocketServer( app.listen(port, '::', () => { diff --git a/packages/insomnia-smoke-test/tests/smoke/git-sync.test.ts b/packages/insomnia-smoke-test/tests/smoke/git-sync.test.ts index c604c4ab8d..f6d1621214 100644 --- a/packages/insomnia-smoke-test/tests/smoke/git-sync.test.ts +++ b/packages/insomnia-smoke-test/tests/smoke/git-sync.test.ts @@ -6,10 +6,19 @@ import { test } from '../../playwright/test'; test.describe('Git Sync', () => { test.slow(); - test('Create new branch and switch to it', async ({ insomnia, page }) => { + test.beforeEach(async ({ insomnia, request }) => { + await request.post('http://127.0.0.1:4010/v1/test-utils/git/setup'); await addAccessTokenGitCredential(insomnia); await insomnia.projectPage.createGitSyncProject(); + }); + test.afterEach(async ({ request }) => { + await request.delete('http://127.0.0.1:4010/v1/test-utils/git/setup'); + }); + + // Creates a git sync project, opens the Branches modal, creates "branch1", + // and verifies the active branch switches to branch1. + test('Create new branch and switch to it', async ({ page }) => { await page.getByTestId('git-dropdown').click(); await page.getByRole('menuitemradio', { name: 'Branches' }).click(); await page.getByRole('textbox', { name: 'New branch name:' }).click(); @@ -18,10 +27,9 @@ test.describe('Git Sync', () => { await expect.soft(page.getByText('branch1 *')).toBeVisible(); }); - test('Commit and check history', async ({ insomnia, page }) => { - await addAccessTokenGitCredential(insomnia); - await insomnia.projectPage.createGitSyncProject(); - + // Creates a collection to produce an unstaged change, stages it, commits with message "1", + // then opens History and verifies the commit appears in the log. + test('Commit and check history', async ({ page }) => { await page.getByRole('button', { name: 'New request collection' }).click(); await page.getByRole('textbox', { name: 'Name', exact: true }).click(); await page.getByRole('textbox', { name: 'Name', exact: true }).press('ControlOrMeta+a'); @@ -44,13 +52,9 @@ test.describe('Git Sync', () => { await expect.soft(page.getByLabel('1', { exact: true }).getByRole('rowheader')).toContainText('1'); }); - test('Merge branch and verify changes on the other branch has been merged into current branch', async ({ - insomnia, - page, - }) => { - await addAccessTokenGitCredential(insomnia); - await insomnia.projectPage.createGitSyncProject(); - + // Creates branch1, commits a new collection on it, switches back to master, + // merges branch1 into master, and verifies the collection is visible on master. + test('Merge branch and verify changes on the other branch has been merged into current branch', async ({ page }) => { await page.getByTestId('git-dropdown').click(); await page.getByRole('menuitemradio', { name: 'Branches' }).click(); await page.getByRole('textbox', { name: 'New branch name:' }).click(); @@ -85,6 +89,77 @@ test.describe('Git Sync', () => { await page.getByTestId('git-project-branches-modal-overlay').waitFor({ state: 'hidden' }); await expect.soft(page.getByText('collection 1')).toBeVisible(); }); + + // Creates a collection, commits it, then pushes to the remote git server. + // Verifies the "Push completed" toast appears, confirming a successful push. + test('Push committed changes to remote', async ({ page }) => { + await page.getByRole('button', { name: 'New request collection' }).click(); + await page.getByRole('textbox', { name: 'Name', exact: true }).click(); + await page.getByRole('textbox', { name: 'Name', exact: true }).press('ControlOrMeta+a'); + await page.getByRole('textbox', { name: 'Name', exact: true }).fill('Push Test Collection'); + await page.getByRole('textbox', { name: 'File name my_collection' }).click(); + await page.getByRole('textbox', { name: 'File name my_collection' }).press('ControlOrMeta+a'); + await page.getByRole('textbox', { name: 'File name my_collection' }).fill('push_test_collection'); + await page.getByRole('button', { name: 'Create', exact: true }).click(); + + await page.getByTestId('git-dropdown').click(); + await page.getByRole('menuitemradio', { name: 'Commit' }).click(); + await page.locator('button[name="Stage all changes"]').click(); + await page.getByRole('textbox', { name: 'Message' }).fill('push test commit'); + await page.getByRole('button', { name: 'Commit', exact: true }).click(); + + await page.getByTestId('git-dropdown').click(); + await page.getByRole('menuitemradio', { name: 'Push' }).click(); + + await expect.soft(page.getByText('Push completed')).toBeVisible(); + }); + + // Creates "branch-to-delete", checks out master, then deletes the branch via the + // two-step PromptButton (Delete → Confirm). Verifies the branch is removed from the list. + test('Delete a branch', async ({ page }) => { + await page.getByTestId('git-dropdown').click(); + await page.getByRole('menuitemradio', { name: 'Branches' }).click(); + await page.getByRole('textbox', { name: 'New branch name:' }).click(); + await page.getByRole('textbox', { name: 'New branch name:' }).fill('branch-to-delete'); + await page.getByRole('button', { name: 'Create', exact: true }).click(); + await expect.soft(page.getByText('branch-to-delete *')).toBeVisible(); + + await page.getByRole('row', { name: 'master' }).getByRole('button', { name: 'Checkout' }).click(); + await expect.soft(page.getByText('master *')).toBeVisible(); + + await page.getByRole('row', { name: 'branch-to-delete' }).getByRole('button', { name: 'Delete' }).click(); + await page.getByRole('row', { name: 'branch-to-delete' }).getByRole('button', { name: 'Confirm' }).click(); + + await expect.soft(page.getByRole('row', { name: 'branch-to-delete' })).toBeHidden(); + + await page.getByTestId('close-git-project-branches-modal').click(); + await page.getByTestId('git-project-branches-modal-overlay').waitFor({ state: 'hidden' }); + await expect.soft(page.getByTestId('git-dropdown')).toContainText('master'); + }); + + // Creates a collection to produce an unstaged change, opens the staging modal, + // clicks "Discard all changes" and confirms. Verifies the modal auto-closes, + // indicating all changes were discarded. + test('Discard all unstaged changes', async ({ page }) => { + await page.getByRole('button', { name: 'New request collection' }).click(); + await page.getByRole('textbox', { name: 'Name', exact: true }).click(); + await page.getByRole('textbox', { name: 'Name', exact: true }).press('ControlOrMeta+a'); + await page.getByRole('textbox', { name: 'Name', exact: true }).fill('Discard Test Collection'); + await page.getByRole('textbox', { name: 'File name my_collection' }).click(); + await page.getByRole('textbox', { name: 'File name my_collection' }).press('ControlOrMeta+a'); + await page.getByRole('textbox', { name: 'File name my_collection' }).fill('discard_test_collection'); + await page.getByRole('button', { name: 'Create', exact: true }).click(); + + await page.getByTestId('git-dropdown').click(); + await page.getByRole('menuitemradio', { name: 'Commit' }).click(); + await expect.soft(page.getByLabel('Unstaged changes').locator('span')).toContainText('discard_test_collection.yaml'); + + await page.locator('button[name="Discard all changes"]').click(); + await page.getByTestId('discard-changes-confirm-button').click(); + + // After discarding all changes the staging modal auto-closes + await expect.soft(page.getByLabel('Unstaged changes')).toBeHidden(); + }); }); async function addAccessTokenGitCredential(insomnia: InsomniaApp) { diff --git a/packages/insomnia/src/ui/components/modals/git-project-staging-modal.tsx b/packages/insomnia/src/ui/components/modals/git-project-staging-modal.tsx index e437fb1409..ba8f203f48 100644 --- a/packages/insomnia/src/ui/components/modals/git-project-staging-modal.tsx +++ b/packages/insomnia/src/ui/components/modals/git-project-staging-modal.tsx @@ -1619,6 +1619,7 @@ const ConfirmDiscardModal = ({ message, onConfirm, onClose }: ConfirmModalProps) Cancel