Git server for smoke test [INS-2258] (#9816)

* Git server for smoke test

* Try to solve flaky test

* feat: remove unused Git hook samples and add Credentials tab functionality

- Deleted various sample Git hook scripts from the git-server fixture, including post-update, pre-applypatch, pre-commit, pre-merge-commit, pre-push, pre-rebase, pre-receive, prepare-commit-msg, push-to-checkout, sendemail-validate, and update hooks.
- Introduced a new PreferencesCredentialsTab class to manage Git credentials within the Insomnia Preferences.
- Updated the PreferencesPage to include the new Credentials tab for Git credentials management.
- Enhanced the ProjectPage with a method to create a Git Sync project, including branch creation and switching.
- Added comprehensive tests for Git Sync functionality, including creating branches, committing changes, and merging branches.
- Updated UI components to support new features, including data-testid attributes for better testability.

Co-authored-by: Copilot <copilot@github.com>

* feat: update path import and add Git sync tests

* revert package.json

* Update package.json

* feat: add new dependencies for Git HTTP mock server and related utilities

* refactor: remove commented-out code in addAccessTokenGitCredential function

* fix: update export tests to use toHaveLength for file count assertions

---------

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
yaoweiprc
2026-04-28 17:44:54 +08:00
committed by GitHub
parent 133f633aeb
commit 933f56854e
22 changed files with 749 additions and 98 deletions

View File

@@ -43,5 +43,6 @@
],
"[cpp]": {
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
}
},
"editor.formatOnPaste": true
}

452
package-lock.json generated
View File

@@ -11591,6 +11591,29 @@
"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",
@@ -11918,6 +11941,29 @@
"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",
@@ -12021,6 +12067,16 @@
"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",
@@ -12241,6 +12297,13 @@
"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",
@@ -13692,6 +13755,16 @@
"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",
@@ -13803,6 +13876,16 @@
"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",
@@ -14508,6 +14591,19 @@
"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",
@@ -16936,6 +17032,31 @@
"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",
@@ -17375,6 +17496,108 @@
"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==",
"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"
}
},
"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==",
"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"
}
},
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -17485,6 +17708,51 @@
"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",
@@ -18033,6 +18301,32 @@
"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",
@@ -20959,6 +21253,16 @@
"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",
@@ -23354,6 +23658,29 @@
"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",
@@ -25979,6 +26306,60 @@
"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",
@@ -26228,6 +26609,15 @@
"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",
@@ -26835,6 +27225,16 @@
"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",
@@ -26898,6 +27298,20 @@
"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",
@@ -27121,6 +27535,16 @@
"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",
@@ -27527,6 +27951,19 @@
"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",
@@ -27537,6 +27974,13 @@
"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",
@@ -28852,6 +29296,13 @@
}
}
},
"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",
@@ -29435,6 +29886,7 @@
"esbuild-runner": "2.2.2",
"express": "^4.21.2",
"express-basic-auth": "^1.2.1",
"git-http-mock-server": "^2.0.0",
"graphql": "^16.10.0",
"graphql-http": "^1.22.4",
"http-errors": "^2.0.0",

View File

@@ -0,0 +1 @@
ref: refs/heads/master

View File

@@ -0,0 +1,6 @@
[core]
repositoryformatversion = 0
filemode = false
bare = true
symlinks = false
ignorecase = true

View File

@@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@@ -0,0 +1,6 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

View File

@@ -0,0 +1,3 @@
x<01><>A
<EFBFBD>0@Ѯs<D1AE><73><05>d☁Rz<52>8<1D>P<1B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'<27><>->_<><5F><EFBFBD><EFBFBD>z<07>ZT-b<>S`<60>؍0R<30>B<EFBFBD><42><EFBFBD>`<18><>$<24>gv&<26>u<EFBFBD><75>)t^<5E><>+E&
<EFBFBD><EFBFBD><EFBFBD>}ߴl<DFB4>;]_G<5F><47><EFBFBD><EFBFBD><0F><><EFBFBD>f]ߓG<DF93>Ķ<EFBFBD>`N=?<3F><><EFBFBD>h<EFBFBD><68><02><>D,

View File

@@ -0,0 +1 @@
73a07b09e3e790de0277df5ac98e0ad62ecf83d4

View File

@@ -30,6 +30,7 @@
"esbuild-runner": "2.2.2",
"express": "^4.21.2",
"express-basic-auth": "^1.2.1",
"git-http-mock-server": "^2.0.0",
"graphql": "^16.10.0",
"graphql-http": "^1.22.4",
"http-errors": "^2.0.0",

View File

@@ -1,4 +1,7 @@
import os from 'node:os';
import type { PlaywrightTestConfig } from '@playwright/test';
const isWindows = os.platform() === 'win32';
const config: PlaywrightTestConfig = {
projects: [
{
@@ -35,7 +38,7 @@ const config: PlaywrightTestConfig = {
},
},
reporter: process.env.CI ? [['github'], ['line']] : [['list']],
timeout: process.env.CI ? 60 * 1000 : 20 * 1000,
timeout: process.env.CI || isWindows ? 60 * 1000 : 20 * 1000,
forbidOnly: !!process.env.CI,
outputDir: 'traces',
testDir: 'tests',

View File

@@ -0,0 +1,38 @@
import type { ElectronApplication, Locator, Page } from '@playwright/test';
import { BasePage } from '../base-page';
/**
* Component for the **Credentials tab** within Insomnia Preferences.
*
* Handles credential management functionality:
* - Add, edit, and remove credentials
*/
export class PreferencesCredentialsTab extends BasePage {
constructor(
readonly page: Page,
readonly app: ElectronApplication,
) {
super(page);
}
get root(): Locator {
return this.page.getByTestId('credentials-settings-tab');
}
async addAccessTokenGitCredential() {
await this.page.getByRole('button', { name: 'Create Git Credential' }).click();
await this.page.getByText('Access Token').click();
await this.page.getByRole('textbox', { name: 'Author Email' }).click();
await this.page.getByRole('textbox', { name: 'Author Email' }).fill('a@b.com');
await this.page.getByRole('textbox', { name: 'Author Name' }).click();
await this.page.getByRole('textbox', { name: 'Author Name' }).fill('author');
await this.page.getByRole('textbox', { name: 'Username' }).click();
await this.page.getByRole('textbox', { name: 'Username' }).fill('username');
await this.page.getByRole('textbox', { name: 'Git Access Token' }).click();
await this.page.getByRole('textbox', { name: 'Git Access Token' }).fill('accesstoken');
await this.page.getByRole('textbox', { name: 'Repository base URL' }).click();
await this.page.getByRole('textbox', { name: 'Repository base URL' }).fill('http://localhost:4010/git/');
await this.page.getByRole('button', { name: 'Save Credential' }).click();
}
}

View File

@@ -1,25 +1,30 @@
import type { ElectronApplication, Locator, Page } from '@playwright/test';
import { PreferencesCredentialsTab } from './credentials-tab';
import { PreferencesDataTab } from './data-tab';
type PreferencesTab = 'Data' | 'General' | 'Themes' | 'Plugins' | 'Other';
type PreferencesTab = 'Data' | 'General' | 'Themes' | 'Credentials' | 'Plugins' | 'Other';
/**
* Page Object for **Insomnia Preferences** modal.
*
* Composes preference tabs:
* - Data tab (import/export)
* - Credentials tab (Git credentials management)
* - Other tabs (themes, plugins, etc.) can be added as needed
*/
export class PreferencesPage {
/** Data tab (import/export functionality). */
readonly dataTab: PreferencesDataTab;
/** Credentials tab (Git credentials management). */
readonly credentialsTab: PreferencesCredentialsTab;
constructor(
readonly page: Page,
readonly app: ElectronApplication,
) {
this.dataTab = new PreferencesDataTab(page, app);
this.credentialsTab = new PreferencesCredentialsTab(page, app);
}
/** The root preferences dialog. */
@@ -43,7 +48,7 @@ export class PreferencesPage {
* Closes the preferences modal.
*/
async closePreferences(): Promise<void> {
await this.page.locator('.app').press('Escape');
await this.page.getByRole('button', { name: 'Modal Close Button' }).click();
await this.root.waitFor({ state: 'hidden' });
}
}

View File

@@ -80,6 +80,33 @@ export class ProjectPage extends BasePage {
await this.page.getByRole('button', { name: 'Create', exact: true }).click();
}
async createGitSyncProject(name = 'My Git Project'): Promise<void> {
await this.page.getByRole('button', { name: 'Create new Project' }).click();
await this.page.getByRole('textbox', { name: 'Project name' }).click();
await this.page.getByRole('textbox', { name: 'Project name' }).press('ControlOrMeta+a');
await this.page.getByRole('textbox', { name: 'Project name' }).fill(name);
await this.page.getByText('Git Sync').click();
await this.page.getByRole('button', { name: 'Access Token author Git' }).click();
await this.page.getByRole('option', { name: 'Custom Git Credential' }).click();
await this.page.getByRole('textbox', { name: 'Repository URL' }).click();
await this.page.getByRole('textbox', { name: 'Repository URL' }).fill('git-server.git');
await this.page.getByRole('button', { name: 'Show suggestions Branch' }).click();
await this.page.getByRole('option', { name: 'master' }).click();
await this.page.getByRole('button', { name: 'Scan for files' }).click();
await this.page.getByRole('button', { name: 'Create Blank Project' }).click();
const projectModalCloseButton = this.page.locator('[data-test-id="project-modal-close-button"]');
await projectModalCloseButton.waitFor({ state: 'visible', timeout: 5000 }).catch(() => {});
if (await projectModalCloseButton.isVisible()) {
await projectModalCloseButton.click();
}
await this.page.getByRole('button', { name: 'Personal workspace' }).click();
await this.page.getByRole('option', { name: /Magic/ }).locator('span').click();
await this.page.getByRole('button', { name: /Magic/ }).click();
await this.page.getByRole('option', { name: 'Personal workspace' }).locator('span').click();
await this.page.getByText('Git Project').waitFor({ state: 'visible', timeout: 10_000 });
await this.page.getByText('Git Project').click();
}
// ===========================================================================
// Import Operations
// ===========================================================================

View File

@@ -6,6 +6,7 @@ import nodePath from 'node:path';
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';
import { basicAuthRouter } from './basic-auth';
@@ -152,6 +153,15 @@ app.get('/v1/oauth/azure/config', (_req, res) => {
});
});
app.use(
'/git',
gitMiddleware({
root: nodePath.join(__dirname, '../fixtures/git-repo'),
glob: '*',
route: '/',
}),
);
startWebSocketServer(
app.listen(port, '::', () => {
console.log(`Listening at http://localhost:${port}`);

View File

@@ -0,0 +1,101 @@
import { expect } from '@playwright/test';
import { test } from '../../playwright/test';
const mockCredentials = {
email: 'insomnia-test@konghq.com',
gitUsername: 'insomnia-test',
username: 'insomnia',
token: '12345',
baseUrl: 'https://fakeurl.com/',
};
test.describe('Git Sync', () => {
test.describe('with git sync feature flag disabled', () => {
test.beforeEach(async ({ request }) => {
// Disable git sync feature flag for organization
await request.post('http://127.0.0.1:4010/v1/test-utils/organizations/features', {
data: {
features: {
gitSync: {
enabled: false,
},
konnectSync: {
enabled: true,
},
},
},
});
});
test.afterEach(async ({ request }) => {
// Re-enable git sync feature flag for organization
await request.post('http://127.0.0.1:4010/v1/test-utils/organizations/features', {
data: {
features: {
gitSync: {
enabled: true,
},
konnectSync: {
enabled: true,
},
},
},
});
});
test('should disable git sync usage', async ({ page }) => {
await page.getByTestId('settings-button').click();
await page.getByRole('tab', { name: 'Credentials' }).click();
await page.getByRole('button', { name: 'Create Git Credential' }).click();
await page.getByText('Access Token').click();
await page.getByRole('textbox', { name: 'Author Email' }).fill(mockCredentials.email);
await page.getByRole('textbox', { name: 'Author Name' }).fill(mockCredentials.gitUsername);
await page.getByRole('textbox', { name: 'Username', exact: true }).fill(mockCredentials.username);
await page.getByRole('textbox', { name: 'Git Access Token' }).fill(mockCredentials.token);
await page.getByRole('textbox', { name: 'Repository base URL' }).fill(mockCredentials.baseUrl);
await page.getByRole('button', { name: 'Save Credential' }).click();
await page.getByRole('button', { name: 'Modal Close Button' }).click();
await page.getByRole('button', { name: 'Create new Project' }).click();
await page.getByLabel('Project Type Item: git').click();
await expect.soft(page.getByLabel('Git Sync Feature Disabled Banner')).toBeVisible();
await expect.soft(page.getByLabel('Git Setup Form')).toBeHidden();
await expect.soft(page.getByRole('button', { name: 'Scan for files' })).toBeDisabled();
});
});
test.describe('with git storage rule disabled', () => {
test.beforeEach(async ({ request }) => {
// Set storage rule to disable git sync
await request.post('http://127.0.0.1:4010/v1/test-utils/organizations/storage-rule', {
data: {
enableCloudSync: true,
enableGitSync: false,
enableLocalVault: true,
isOverridden: false,
},
});
});
test.afterEach(async ({ request }) => {
// reset the storage rule after test
await request.post('http://127.0.0.1:4010/v1/test-utils/organizations/storage-rule', {
data: {
enableCloudSync: true,
enableGitSync: true,
enableLocalVault: true,
isOverridden: false,
},
});
});
test('disable git sync selection', async ({ page }) => {
await page.getByRole('button', { name: 'Create new Project' }).click();
const banner = page.getByLabel('Project Storage Restriction Banner');
await expect.soft(banner).toBeVisible();
await expect.soft(banner).not.toHaveText('Git Sync');
await expect.soft(page.getByLabel('Project Type: git')).toBeDisabled();
});
});
});

View File

@@ -33,9 +33,8 @@ test.describe('Export', () => {
await insomnia.preferencesPage.switchToPreferenceTab('Data');
await insomnia.preferencesPage.dataTab.exportProjectData(tempDir, 'yaml');
await waitForExportFiles(tempDir, 2);
await insomnia.preferencesPage.closePreferences();
const exportedFiles = getExportedFiles(tempDir);
expect.soft(exportedFiles.length).toBe(2);
expect.soft(exportedFiles).toHaveLength(2);
const fixtureMap: Record<string, string> = {
'Collection-A': FIXTURE_FILES[0],
'Collection-B': FIXTURE_FILES[1],
@@ -78,7 +77,7 @@ test.describe('Export', () => {
await insomnia.preferencesPage.dataTab.exportAllData(tempDir);
await insomnia.preferencesPage.closePreferences();
const exportedFiles = getExportedFiles(tempDir).filter((file: string) => !file.includes('scratchpad'));
expect.soft(exportedFiles.length).toBe(2);
expect.soft(exportedFiles).toHaveLength(2);
const fixtureMap: Record<string, string> = {
'Collection-A': FIXTURE_FILES[0],
'Collection-B': FIXTURE_FILES[1],
@@ -123,8 +122,6 @@ test.describe('Export', () => {
await insomnia.preferencesPage.dataTab.exportProjectData(exportFilePath, 'har');
await waitForExportFiles(tempDir, 1);
await insomnia.preferencesPage.closePreferences();
const exportedContent = readExportedFile(exportFilePath);
const har = JSON.parse(exportedContent);

View File

@@ -1,101 +1,96 @@
import { expect } from '@playwright/test';
import type { InsomniaApp } from '../../playwright/pages';
import { test } from '../../playwright/test';
const mockCredentials = {
email: 'insomnia-test@konghq.com',
gitUsername: 'insomnia-test',
username: 'insomnia',
token: '12345',
baseUrl: 'https://fakeurl.com/',
};
test.describe('Git Sync', () => {
test.describe('with git sync feature flag disabled', () => {
test.beforeEach(async ({ request }) => {
// Disable git sync feature flag for organization
await request.post('http://127.0.0.1:4010/v1/test-utils/organizations/features', {
data: {
features: {
gitSync: {
enabled: false,
},
konnectSync: {
enabled: true,
},
},
},
});
});
test.slow();
test.afterEach(async ({ request }) => {
// Re-enable git sync feature flag for organization
await request.post('http://127.0.0.1:4010/v1/test-utils/organizations/features', {
data: {
features: {
gitSync: {
enabled: true,
},
konnectSync: {
enabled: true,
},
},
},
});
});
test('Create new branch and switch to it', async ({ insomnia, page }) => {
await addAccessTokenGitCredential(insomnia);
await insomnia.projectPage.createGitSyncProject();
test('should disable git sync usage', async ({ page }) => {
await page.getByTestId('settings-button').click();
await page.getByRole('tab', { name: 'Credentials' }).click();
await page.getByRole('button', { name: 'Create Git Credential' }).click();
await page.getByText('Access Token').click();
await page.getByRole('textbox', { name: 'Author Email' }).fill(mockCredentials.email);
await page.getByRole('textbox', { name: 'Author Name' }).fill(mockCredentials.gitUsername);
await page.getByRole('textbox', { name: 'Username', exact: true }).fill(mockCredentials.username);
await page.getByRole('textbox', { name: 'Git Access Token' }).fill(mockCredentials.token);
await page.getByRole('textbox', { name: 'Repository base URL' }).fill(mockCredentials.baseUrl);
await page.getByRole('button', { name: 'Save Credential' }).click();
await page.getByRole('button', { name: 'Modal Close Button' }).click();
await page.getByRole('button', { name: 'Create new Project' }).click();
await page.getByLabel('Project Type Item: git').click();
await expect.soft(page.getByLabel('Git Sync Feature Disabled Banner')).toBeVisible();
await expect.soft(page.getByLabel('Git Setup Form')).toBeHidden();
await expect.soft(page.getByRole('button', { name: 'Scan for files' })).toBeDisabled();
});
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('branch1');
await page.getByRole('button', { name: 'Create', exact: true }).click();
await expect.soft(page.getByText('branch1 *')).toBeVisible();
});
test.describe('with git storage rule disabled', () => {
test.beforeEach(async ({ request }) => {
// Set storage rule to disable git sync
await request.post('http://127.0.0.1:4010/v1/test-utils/organizations/storage-rule', {
data: {
enableCloudSync: true,
enableGitSync: false,
enableLocalVault: true,
isOverridden: false,
},
});
});
test('Commit and check history', async ({ insomnia, page }) => {
await addAccessTokenGitCredential(insomnia);
await insomnia.projectPage.createGitSyncProject();
test.afterEach(async ({ request }) => {
// reset the storage rule after test
await request.post('http://127.0.0.1:4010/v1/test-utils/organizations/storage-rule', {
data: {
enableCloudSync: true,
enableGitSync: true,
enableLocalVault: true,
isOverridden: false,
},
});
});
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('Collection 1');
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('collection_1');
await page.getByRole('button', { name: 'Create', exact: true }).click();
await page.getByTestId('git-dropdown').click();
await expect.soft(page.getByRole('menuitemradio', { name: 'Commit' })).toBeVisible();
await page.getByRole('menuitemradio', { name: 'Commit' }).click();
await expect.soft(page.getByLabel('Unstaged changes').locator('span')).toContainText('collection_1.yaml');
test('disable git sync selection', async ({ page }) => {
await page.getByRole('button', { name: 'Create new Project' }).click();
const banner = page.getByLabel('Project Storage Restriction Banner');
await expect.soft(banner).toBeVisible();
await expect.soft(banner).not.toHaveText('Git Sync');
await expect.soft(page.getByLabel('Project Type: git')).toBeDisabled();
});
await page.locator('button[name="Stage all changes"]').click();
await page.getByRole('textbox', { name: 'Message' }).click();
await page.getByRole('textbox', { name: 'Message' }).fill('1');
await page.getByRole('button', { name: 'Commit', exact: true }).click();
await page.getByTestId('git-dropdown').click();
await page.getByText('History').click();
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();
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('branch1');
await page.getByRole('button', { name: 'Create', exact: true }).click();
await expect.soft(page.getByText('branch1 *')).toBeVisible();
await page.getByTestId('close-git-project-branches-modal').click();
await page.getByTestId('git-project-branches-modal-overlay').waitFor({ state: 'hidden' });
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('collection 1');
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('collection_1');
await page.getByRole('button', { name: 'Create', exact: true }).click();
await page.getByTestId('project').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' }).click();
await page.getByRole('textbox', { name: 'Message' }).fill('commit 1');
await page.getByRole('button', { name: 'Commit', exact: true }).click();
await page.getByTestId('git-dropdown').click();
await page.getByRole('menuitemradio', { name: 'master' }).click();
await page.locator('html').click();
await page.getByTestId('git-dropdown').click();
await page.getByRole('menuitemradio', { name: 'Branches' }).click();
await page.getByLabel('branch1').getByRole('button', { name: 'Merge' }).click();
await page.getByRole('button', { name: ' Confirm' }).click();
await page.getByTestId('close-git-project-branches-modal').click();
await page.getByTestId('git-project-branches-modal-overlay').waitFor({ state: 'hidden' });
await expect.soft(page.getByText('collection 1')).toBeVisible();
});
});
async function addAccessTokenGitCredential(insomnia: InsomniaApp) {
await insomnia.statusbar.openPreferences();
await insomnia.preferencesPage.switchToPreferenceTab('Credentials');
await insomnia.preferencesPage.credentialsTab.addAccessTokenGitCredential();
await expect.soft(insomnia.page.getByRole('row', { name: 'Custom Git Credential' })).toBeVisible();
await insomnia.preferencesPage.closePreferences();
}

View File

@@ -311,6 +311,7 @@ export const GitProjectBranchesModal: FC<Props> = ({ currentBranch, branches, on
}}
isDismissable
className="fixed top-0 left-0 z-10 flex h-(--visual-viewport-height) w-full items-center justify-center bg-black/30"
data-testid="git-project-branches-modal-overlay"
>
<Modal
onOpenChange={isOpen => {
@@ -328,6 +329,7 @@ export const GitProjectBranchesModal: FC<Props> = ({ currentBranch, branches, on
<Button
className="flex aspect-square h-6 shrink-0 items-center justify-center rounded-xs text-sm text-(--color-font) ring-1 ring-transparent transition-all hover:bg-(--hl-xs) focus:ring-(--hl-md) focus:ring-inset aria-pressed:bg-(--hl-sm)"
onPress={close}
data-testid="close-git-project-branches-modal"
>
<Icon icon="x" />
</Button>

View File

@@ -64,6 +64,7 @@ export const ProjectModal = ({
</Heading>
<Button
className="flex aspect-square h-6 shrink-0 items-center justify-center rounded-xs text-sm text-(--color-font) ring-1 ring-transparent transition-all hover:bg-(--hl-xs) focus:ring-(--hl-md) focus:ring-inset aria-pressed:bg-(--hl-sm)"
data-test-id="project-modal-close-button"
onPress={close}
>
<Icon icon="x" />

View File

@@ -696,7 +696,7 @@ const GitCredentialsList = () => {
export const CredentialsSettings = () => {
return (
<div>
<div data-testid="credentials-settings-tab">
<GitCredentialsList />
<CloudServiceCredentialList />
</div>