mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 19:06:18 +01:00 
			
		
		
		
	Add typescript guideline and typescript-specific eslint plugins and fix issues (#31521)
1. Add some general guidelines how to write our typescript code 2. Add `@typescript-eslint/eslint-plugin`, general typescript rules 3. Add `eslint-plugin-deprecation` to detect deprecated code 4. Fix all new lint issues that came up
This commit is contained in:
		
							
								
								
									
										133
									
								
								.eslintrc.yaml
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								.eslintrc.yaml
									
									
									
									
									
								
							| @@ -13,6 +13,7 @@ parserOptions: | |||||||
|   ecmaVersion: latest |   ecmaVersion: latest | ||||||
|   project: true |   project: true | ||||||
|   extraFileExtensions: [".vue"] |   extraFileExtensions: [".vue"] | ||||||
|  |   parser: "@typescript-eslint/parser" # for vue plugin - https://eslint.vuejs.org/user-guide/#how-to-use-a-custom-parser | ||||||
|  |  | ||||||
| settings: | settings: | ||||||
|   import/extensions: [".js", ".ts"] |   import/extensions: [".js", ".ts"] | ||||||
| @@ -24,7 +25,9 @@ settings: | |||||||
| plugins: | plugins: | ||||||
|   - "@eslint-community/eslint-plugin-eslint-comments" |   - "@eslint-community/eslint-plugin-eslint-comments" | ||||||
|   - "@stylistic/eslint-plugin-js" |   - "@stylistic/eslint-plugin-js" | ||||||
|  |   - "@typescript-eslint/eslint-plugin" | ||||||
|   - eslint-plugin-array-func |   - eslint-plugin-array-func | ||||||
|  |   - eslint-plugin-deprecation | ||||||
|   - eslint-plugin-github |   - eslint-plugin-github | ||||||
|   - eslint-plugin-i |   - eslint-plugin-i | ||||||
|   - eslint-plugin-no-jquery |   - eslint-plugin-no-jquery | ||||||
| @@ -209,6 +212,123 @@ rules: | |||||||
|   "@stylistic/js/wrap-iife": [2, inside] |   "@stylistic/js/wrap-iife": [2, inside] | ||||||
|   "@stylistic/js/wrap-regex": [0] |   "@stylistic/js/wrap-regex": [0] | ||||||
|   "@stylistic/js/yield-star-spacing": [2, after] |   "@stylistic/js/yield-star-spacing": [2, after] | ||||||
|  |   "@typescript-eslint/adjacent-overload-signatures": [0] | ||||||
|  |   "@typescript-eslint/array-type": [0] | ||||||
|  |   "@typescript-eslint/await-thenable": [2] | ||||||
|  |   "@typescript-eslint/ban-ts-comment": [2, {'ts-expect-error': false, 'ts-ignore': true, 'ts-nocheck': false, 'ts-check': false}] | ||||||
|  |   "@typescript-eslint/ban-tslint-comment": [0] | ||||||
|  |   "@typescript-eslint/ban-types": [2, {extendDefaults: true, types: {Function: false}}] | ||||||
|  |   "@typescript-eslint/class-literal-property-style": [0] | ||||||
|  |   "@typescript-eslint/class-methods-use-this": [0] | ||||||
|  |   "@typescript-eslint/consistent-generic-constructors": [0] | ||||||
|  |   "@typescript-eslint/consistent-indexed-object-style": [0] | ||||||
|  |   "@typescript-eslint/consistent-return": [0] | ||||||
|  |   "@typescript-eslint/consistent-type-assertions": [2, {assertionStyle: as, objectLiteralTypeAssertions: allow}] | ||||||
|  |   "@typescript-eslint/consistent-type-definitions": [2, type] | ||||||
|  |   "@typescript-eslint/consistent-type-exports": [2, {fixMixedExportsWithInlineTypeSpecifier: false}] | ||||||
|  |   "@typescript-eslint/consistent-type-imports": [2, {prefer: type-imports, fixStyle: separate-type-imports, disallowTypeAnnotations: true}] | ||||||
|  |   "@typescript-eslint/default-param-last": [0] | ||||||
|  |   "@typescript-eslint/dot-notation": [0] | ||||||
|  |   "@typescript-eslint/explicit-function-return-type": [0] | ||||||
|  |   "@typescript-eslint/explicit-member-accessibility": [0] | ||||||
|  |   "@typescript-eslint/explicit-module-boundary-types": [0] | ||||||
|  |   "@typescript-eslint/init-declarations": [0] | ||||||
|  |   "@typescript-eslint/max-params": [0] | ||||||
|  |   "@typescript-eslint/member-ordering": [0] | ||||||
|  |   "@typescript-eslint/method-signature-style": [0] | ||||||
|  |   "@typescript-eslint/naming-convention": [0] | ||||||
|  |   "@typescript-eslint/no-array-constructor": [2] | ||||||
|  |   "@typescript-eslint/no-array-delete": [2] | ||||||
|  |   "@typescript-eslint/no-base-to-string": [0] | ||||||
|  |   "@typescript-eslint/no-confusing-non-null-assertion": [2] | ||||||
|  |   "@typescript-eslint/no-confusing-void-expression": [0] | ||||||
|  |   "@typescript-eslint/no-dupe-class-members": [0] | ||||||
|  |   "@typescript-eslint/no-duplicate-enum-values": [2] | ||||||
|  |   "@typescript-eslint/no-duplicate-type-constituents": [2, {ignoreUnions: true}] | ||||||
|  |   "@typescript-eslint/no-dynamic-delete": [0] | ||||||
|  |   "@typescript-eslint/no-empty-function": [0] | ||||||
|  |   "@typescript-eslint/no-empty-interface": [0] | ||||||
|  |   "@typescript-eslint/no-explicit-any": [0] | ||||||
|  |   "@typescript-eslint/no-extra-non-null-assertion": [2] | ||||||
|  |   "@typescript-eslint/no-extraneous-class": [0] | ||||||
|  |   "@typescript-eslint/no-floating-promises": [0] | ||||||
|  |   "@typescript-eslint/no-for-in-array": [2] | ||||||
|  |   "@typescript-eslint/no-implied-eval": [2] | ||||||
|  |   "@typescript-eslint/no-import-type-side-effects": [0] # dupe with consistent-type-imports | ||||||
|  |   "@typescript-eslint/no-inferrable-types": [0] | ||||||
|  |   "@typescript-eslint/no-invalid-this": [0] | ||||||
|  |   "@typescript-eslint/no-invalid-void-type": [0] | ||||||
|  |   "@typescript-eslint/no-loop-func": [0] | ||||||
|  |   "@typescript-eslint/no-loss-of-precision": [2] | ||||||
|  |   "@typescript-eslint/no-magic-numbers": [0] | ||||||
|  |   "@typescript-eslint/no-meaningless-void-operator": [0] | ||||||
|  |   "@typescript-eslint/no-misused-new": [2] | ||||||
|  |   "@typescript-eslint/no-misused-promises": [2, {checksVoidReturn: {attributes: false, arguments: false}}] | ||||||
|  |   "@typescript-eslint/no-mixed-enums": [0] | ||||||
|  |   "@typescript-eslint/no-namespace": [2] | ||||||
|  |   "@typescript-eslint/no-non-null-asserted-nullish-coalescing": [0] | ||||||
|  |   "@typescript-eslint/no-non-null-asserted-optional-chain": [2] | ||||||
|  |   "@typescript-eslint/no-non-null-assertion": [0] | ||||||
|  |   "@typescript-eslint/no-redeclare": [0] | ||||||
|  |   "@typescript-eslint/no-redundant-type-constituents": [2] | ||||||
|  |   "@typescript-eslint/no-require-imports": [0] | ||||||
|  |   "@typescript-eslint/no-restricted-imports": [0] | ||||||
|  |   "@typescript-eslint/no-shadow": [0] | ||||||
|  |   "@typescript-eslint/no-this-alias": [0] # handled by unicorn/no-this-assignment | ||||||
|  |   "@typescript-eslint/no-unnecessary-boolean-literal-compare": [0] | ||||||
|  |   "@typescript-eslint/no-unnecessary-condition": [0] | ||||||
|  |   "@typescript-eslint/no-unnecessary-qualifier": [0] | ||||||
|  |   "@typescript-eslint/no-unnecessary-template-expression": [0] | ||||||
|  |   "@typescript-eslint/no-unnecessary-type-arguments": [0] | ||||||
|  |   "@typescript-eslint/no-unnecessary-type-assertion": [2] | ||||||
|  |   "@typescript-eslint/no-unnecessary-type-constraint": [2] | ||||||
|  |   "@typescript-eslint/no-unsafe-argument": [0] | ||||||
|  |   "@typescript-eslint/no-unsafe-assignment": [0] | ||||||
|  |   "@typescript-eslint/no-unsafe-call": [0] | ||||||
|  |   "@typescript-eslint/no-unsafe-declaration-merging": [2] | ||||||
|  |   "@typescript-eslint/no-unsafe-enum-comparison": [2] | ||||||
|  |   "@typescript-eslint/no-unsafe-member-access": [0] | ||||||
|  |   "@typescript-eslint/no-unsafe-return": [0] | ||||||
|  |   "@typescript-eslint/no-unsafe-unary-minus": [2] | ||||||
|  |   "@typescript-eslint/no-unused-expressions": [0] | ||||||
|  |   "@typescript-eslint/no-unused-vars": [2, {vars: all, args: all, caughtErrors: all, ignoreRestSiblings: false, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_}] | ||||||
|  |   "@typescript-eslint/no-use-before-define": [0] | ||||||
|  |   "@typescript-eslint/no-useless-constructor": [0] | ||||||
|  |   "@typescript-eslint/no-useless-empty-export": [0] | ||||||
|  |   "@typescript-eslint/no-var-requires": [2] | ||||||
|  |   "@typescript-eslint/non-nullable-type-assertion-style": [0] | ||||||
|  |   "@typescript-eslint/only-throw-error": [2] | ||||||
|  |   "@typescript-eslint/parameter-properties": [0] | ||||||
|  |   "@typescript-eslint/prefer-as-const": [2] | ||||||
|  |   "@typescript-eslint/prefer-destructuring": [0] | ||||||
|  |   "@typescript-eslint/prefer-enum-initializers": [0] | ||||||
|  |   "@typescript-eslint/prefer-find": [2] | ||||||
|  |   "@typescript-eslint/prefer-for-of": [2] | ||||||
|  |   "@typescript-eslint/prefer-function-type": [2] | ||||||
|  |   "@typescript-eslint/prefer-includes": [2] | ||||||
|  |   "@typescript-eslint/prefer-literal-enum-member": [0] | ||||||
|  |   "@typescript-eslint/prefer-namespace-keyword": [0] | ||||||
|  |   "@typescript-eslint/prefer-nullish-coalescing": [0] | ||||||
|  |   "@typescript-eslint/prefer-optional-chain": [2, {requireNullish: true}] | ||||||
|  |   "@typescript-eslint/prefer-promise-reject-errors": [0] | ||||||
|  |   "@typescript-eslint/prefer-readonly": [0] | ||||||
|  |   "@typescript-eslint/prefer-readonly-parameter-types": [0] | ||||||
|  |   "@typescript-eslint/prefer-reduce-type-parameter": [0] | ||||||
|  |   "@typescript-eslint/prefer-regexp-exec": [0] | ||||||
|  |   "@typescript-eslint/prefer-return-this-type": [0] | ||||||
|  |   "@typescript-eslint/prefer-string-starts-ends-with": [2, {allowSingleElementEquality: always}] | ||||||
|  |   "@typescript-eslint/promise-function-async": [0] | ||||||
|  |   "@typescript-eslint/require-array-sort-compare": [0] | ||||||
|  |   "@typescript-eslint/require-await": [0] | ||||||
|  |   "@typescript-eslint/restrict-plus-operands": [2] | ||||||
|  |   "@typescript-eslint/restrict-template-expressions": [0] | ||||||
|  |   "@typescript-eslint/return-await": [0] | ||||||
|  |   "@typescript-eslint/strict-boolean-expressions": [0] | ||||||
|  |   "@typescript-eslint/switch-exhaustiveness-check": [0] | ||||||
|  |   "@typescript-eslint/triple-slash-reference": [2] | ||||||
|  |   "@typescript-eslint/typedef": [0] | ||||||
|  |   "@typescript-eslint/unbound-method": [2] | ||||||
|  |   "@typescript-eslint/unified-signatures": [2] | ||||||
|   accessor-pairs: [2] |   accessor-pairs: [2] | ||||||
|   array-callback-return: [2, {checkForEach: true}] |   array-callback-return: [2, {checkForEach: true}] | ||||||
|   array-func/avoid-reverse: [2] |   array-func/avoid-reverse: [2] | ||||||
| @@ -230,6 +350,7 @@ rules: | |||||||
|   default-case-last: [2] |   default-case-last: [2] | ||||||
|   default-case: [0] |   default-case: [0] | ||||||
|   default-param-last: [0] |   default-param-last: [0] | ||||||
|  |   deprecation/deprecation: [2] | ||||||
|   dot-notation: [0] |   dot-notation: [0] | ||||||
|   eqeqeq: [2] |   eqeqeq: [2] | ||||||
|   for-direction: [2] |   for-direction: [2] | ||||||
| @@ -321,7 +442,7 @@ rules: | |||||||
|   multiline-comment-style: [2, separate-lines] |   multiline-comment-style: [2, separate-lines] | ||||||
|   new-cap: [0] |   new-cap: [0] | ||||||
|   no-alert: [0] |   no-alert: [0] | ||||||
|   no-array-constructor: [2] |   no-array-constructor: [0] # handled by @typescript-eslint/no-array-constructor | ||||||
|   no-async-promise-executor: [0] |   no-async-promise-executor: [0] | ||||||
|   no-await-in-loop: [0] |   no-await-in-loop: [0] | ||||||
|   no-bitwise: [0] |   no-bitwise: [0] | ||||||
| @@ -365,7 +486,7 @@ rules: | |||||||
|   no-global-assign: [2] |   no-global-assign: [2] | ||||||
|   no-implicit-coercion: [2] |   no-implicit-coercion: [2] | ||||||
|   no-implicit-globals: [0] |   no-implicit-globals: [0] | ||||||
|   no-implied-eval: [2] |   no-implied-eval: [0] # handled by @typescript-eslint/no-implied-eval | ||||||
|   no-import-assign: [2] |   no-import-assign: [2] | ||||||
|   no-inline-comments: [0] |   no-inline-comments: [0] | ||||||
|   no-inner-declarations: [2] |   no-inner-declarations: [2] | ||||||
| @@ -471,7 +592,7 @@ rules: | |||||||
|   no-lone-blocks: [2] |   no-lone-blocks: [2] | ||||||
|   no-lonely-if: [0] |   no-lonely-if: [0] | ||||||
|   no-loop-func: [0] |   no-loop-func: [0] | ||||||
|   no-loss-of-precision: [2] |   no-loss-of-precision: [0] # handled by @typescript-eslint/no-loss-of-precision | ||||||
|   no-magic-numbers: [0] |   no-magic-numbers: [0] | ||||||
|   no-misleading-character-class: [2] |   no-misleading-character-class: [2] | ||||||
|   no-multi-assign: [0] |   no-multi-assign: [0] | ||||||
| @@ -493,7 +614,7 @@ rules: | |||||||
|   no-promise-executor-return: [0] |   no-promise-executor-return: [0] | ||||||
|   no-proto: [2] |   no-proto: [2] | ||||||
|   no-prototype-builtins: [2] |   no-prototype-builtins: [2] | ||||||
|   no-redeclare: [2] |   no-redeclare: [0] # must be disabled for typescript overloads | ||||||
|   no-regex-spaces: [2] |   no-regex-spaces: [2] | ||||||
|   no-restricted-exports: [0] |   no-restricted-exports: [0] | ||||||
|   no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top, __dirname, __filename] |   no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top, __dirname, __filename] | ||||||
| @@ -526,7 +647,7 @@ rules: | |||||||
|   no-unused-expressions: [2] |   no-unused-expressions: [2] | ||||||
|   no-unused-labels: [2] |   no-unused-labels: [2] | ||||||
|   no-unused-private-class-members: [2] |   no-unused-private-class-members: [2] | ||||||
|   no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, caughtErrorsIgnorePattern: ^_, destructuredArrayIgnorePattern: ^_, ignoreRestSiblings: false}] |   no-unused-vars: [0] # handled by @typescript-eslint/no-unused-vars | ||||||
|   no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}] |   no-use-before-define: [2, {functions: false, classes: true, variables: true, allowNamedExports: true}] | ||||||
|   no-use-extend-native/no-use-extend-native: [2] |   no-use-extend-native/no-use-extend-native: [2] | ||||||
|   no-useless-backreference: [2] |   no-useless-backreference: [2] | ||||||
| @@ -641,7 +762,7 @@ rules: | |||||||
|   regexp/unicode-escape: [0] |   regexp/unicode-escape: [0] | ||||||
|   regexp/use-ignore-case: [0] |   regexp/use-ignore-case: [0] | ||||||
|   require-atomic-updates: [0] |   require-atomic-updates: [0] | ||||||
|   require-await: [0] |   require-await: [0] # handled by @typescript-eslint/require-await | ||||||
|   require-unicode-regexp: [0] |   require-unicode-regexp: [0] | ||||||
|   require-yield: [2] |   require-yield: [2] | ||||||
|   sonarjs/cognitive-complexity: [0] |   sonarjs/cognitive-complexity: [0] | ||||||
|   | |||||||
| @@ -79,6 +79,22 @@ We use htmx for simple interactions. You can see an example for simple interacti | |||||||
| Although mixing different frameworks is discouraged, | Although mixing different frameworks is discouraged, | ||||||
| it should also work if the mixing is necessary and the code is well-designed and maintainable. | it should also work if the mixing is necessary and the code is well-designed and maintainable. | ||||||
|  |  | ||||||
|  | ### Typescript | ||||||
|  |  | ||||||
|  | Gitea is in the process of migrating to type-safe Typescript. Here are some specific guidelines regarding Typescript in the codebase: | ||||||
|  |  | ||||||
|  | #### Use type aliases instead of interfaces | ||||||
|  |  | ||||||
|  | Prefer to use type aliases because they can represent any type and are generally more flexible to use than interfaces. | ||||||
|  |  | ||||||
|  | #### Use separate type imports | ||||||
|  |  | ||||||
|  | We use `verbatimModuleSyntax` so type and non-type imports from the same file must be split into two `import type` statements. This enables the typescript compiler to completely eliminate the type import statements during compilation. | ||||||
|  |  | ||||||
|  | #### Use `@ts-expect-error` instead of `@ts-ignore` | ||||||
|  |  | ||||||
|  | Both annotations should be avoided, but if you have to use them, use `@ts-expect-error` because it will not leave ineffective statements after the issue is fixed. | ||||||
|  |  | ||||||
| ### `async` Functions | ### `async` Functions | ||||||
|  |  | ||||||
| Only mark a function as `async` if and only if there are `await` calls | Only mark a function as `async` if and only if there are `await` calls | ||||||
|   | |||||||
							
								
								
									
										230
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										230
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -69,11 +69,13 @@ | |||||||
|         "@stoplight/spectral-cli": "6.11.1", |         "@stoplight/spectral-cli": "6.11.1", | ||||||
|         "@stylistic/eslint-plugin-js": "2.2.1", |         "@stylistic/eslint-plugin-js": "2.2.1", | ||||||
|         "@stylistic/stylelint-plugin": "2.1.2", |         "@stylistic/stylelint-plugin": "2.1.2", | ||||||
|  |         "@typescript-eslint/eslint-plugin": "7.14.1", | ||||||
|         "@typescript-eslint/parser": "7.14.1", |         "@typescript-eslint/parser": "7.14.1", | ||||||
|         "@vitejs/plugin-vue": "5.0.5", |         "@vitejs/plugin-vue": "5.0.5", | ||||||
|         "eslint": "8.57.0", |         "eslint": "8.57.0", | ||||||
|         "eslint-import-resolver-typescript": "3.6.1", |         "eslint-import-resolver-typescript": "3.6.1", | ||||||
|         "eslint-plugin-array-func": "4.0.0", |         "eslint-plugin-array-func": "4.0.0", | ||||||
|  |         "eslint-plugin-deprecation": "3.0.0", | ||||||
|         "eslint-plugin-github": "5.0.1", |         "eslint-plugin-github": "5.0.1", | ||||||
|         "eslint-plugin-i": "2.29.1", |         "eslint-plugin-i": "2.29.1", | ||||||
|         "eslint-plugin-no-jquery": "3.0.1", |         "eslint-plugin-no-jquery": "3.0.1", | ||||||
| @@ -2370,16 +2372,17 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/@typescript-eslint/eslint-plugin": { |     "node_modules/@typescript-eslint/eslint-plugin": { | ||||||
|       "version": "7.13.1", |       "version": "7.14.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", |       "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz", | ||||||
|       "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", |       "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "@eslint-community/regexpp": "^4.10.0", |         "@eslint-community/regexpp": "^4.10.0", | ||||||
|         "@typescript-eslint/scope-manager": "7.13.1", |         "@typescript-eslint/scope-manager": "7.14.1", | ||||||
|         "@typescript-eslint/type-utils": "7.13.1", |         "@typescript-eslint/type-utils": "7.14.1", | ||||||
|         "@typescript-eslint/utils": "7.13.1", |         "@typescript-eslint/utils": "7.14.1", | ||||||
|         "@typescript-eslint/visitor-keys": "7.13.1", |         "@typescript-eslint/visitor-keys": "7.14.1", | ||||||
|         "graphemer": "^1.4.0", |         "graphemer": "^1.4.0", | ||||||
|         "ignore": "^5.3.1", |         "ignore": "^5.3.1", | ||||||
|         "natural-compare": "^1.4.0", |         "natural-compare": "^1.4.0", | ||||||
| @@ -2431,7 +2434,7 @@ | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { |     "node_modules/@typescript-eslint/scope-manager": { | ||||||
|       "version": "7.14.1", |       "version": "7.14.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", |       "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", | ||||||
|       "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", |       "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", | ||||||
| @@ -2449,7 +2452,35 @@ | |||||||
|         "url": "https://opencollective.com/typescript-eslint" |         "url": "https://opencollective.com/typescript-eslint" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { |     "node_modules/@typescript-eslint/type-utils": { | ||||||
|  |       "version": "7.14.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz", | ||||||
|  |       "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@typescript-eslint/typescript-estree": "7.14.1", | ||||||
|  |         "@typescript-eslint/utils": "7.14.1", | ||||||
|  |         "debug": "^4.3.4", | ||||||
|  |         "ts-api-utils": "^1.3.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": "^18.18.0 || >=20.0.0" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "type": "opencollective", | ||||||
|  |         "url": "https://opencollective.com/typescript-eslint" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "eslint": "^8.56.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependenciesMeta": { | ||||||
|  |         "typescript": { | ||||||
|  |           "optional": true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@typescript-eslint/types": { | ||||||
|       "version": "7.14.1", |       "version": "7.14.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", |       "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", | ||||||
|       "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", |       "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", | ||||||
| @@ -2463,7 +2494,7 @@ | |||||||
|         "url": "https://opencollective.com/typescript-eslint" |         "url": "https://opencollective.com/typescript-eslint" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { |     "node_modules/@typescript-eslint/typescript-estree": { | ||||||
|       "version": "7.14.1", |       "version": "7.14.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", |       "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", | ||||||
|       "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", |       "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", | ||||||
| @@ -2492,7 +2523,30 @@ | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { |     "node_modules/@typescript-eslint/utils": { | ||||||
|  |       "version": "7.14.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", | ||||||
|  |       "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@eslint-community/eslint-utils": "^4.4.0", | ||||||
|  |         "@typescript-eslint/scope-manager": "7.14.1", | ||||||
|  |         "@typescript-eslint/types": "7.14.1", | ||||||
|  |         "@typescript-eslint/typescript-estree": "7.14.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": "^18.18.0 || >=20.0.0" | ||||||
|  |       }, | ||||||
|  |       "funding": { | ||||||
|  |         "type": "opencollective", | ||||||
|  |         "url": "https://opencollective.com/typescript-eslint" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "eslint": "^8.56.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@typescript-eslint/visitor-keys": { | ||||||
|       "version": "7.14.1", |       "version": "7.14.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", |       "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", | ||||||
|       "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", |       "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", | ||||||
| @@ -2510,148 +2564,12 @@ | |||||||
|         "url": "https://opencollective.com/typescript-eslint" |         "url": "https://opencollective.com/typescript-eslint" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { |  | ||||||
|       "version": "3.4.3", |  | ||||||
|       "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", |  | ||||||
|       "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", |  | ||||||
|       "dev": true, |  | ||||||
|       "license": "Apache-2.0", |  | ||||||
|       "engines": { |  | ||||||
|         "node": "^12.22.0 || ^14.17.0 || >=16.0.0" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "url": "https://opencollective.com/eslint" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/@typescript-eslint/scope-manager": { |  | ||||||
|       "version": "7.13.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", |  | ||||||
|       "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", |  | ||||||
|       "dev": true, |  | ||||||
|       "dependencies": { |  | ||||||
|         "@typescript-eslint/types": "7.13.1", |  | ||||||
|         "@typescript-eslint/visitor-keys": "7.13.1" |  | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": "^18.18.0 || >=20.0.0" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "type": "opencollective", |  | ||||||
|         "url": "https://opencollective.com/typescript-eslint" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/@typescript-eslint/type-utils": { |  | ||||||
|       "version": "7.13.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", |  | ||||||
|       "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", |  | ||||||
|       "dev": true, |  | ||||||
|       "dependencies": { |  | ||||||
|         "@typescript-eslint/typescript-estree": "7.13.1", |  | ||||||
|         "@typescript-eslint/utils": "7.13.1", |  | ||||||
|         "debug": "^4.3.4", |  | ||||||
|         "ts-api-utils": "^1.3.0" |  | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": "^18.18.0 || >=20.0.0" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "type": "opencollective", |  | ||||||
|         "url": "https://opencollective.com/typescript-eslint" |  | ||||||
|       }, |  | ||||||
|       "peerDependencies": { |  | ||||||
|         "eslint": "^8.56.0" |  | ||||||
|       }, |  | ||||||
|       "peerDependenciesMeta": { |  | ||||||
|         "typescript": { |  | ||||||
|           "optional": true |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/@typescript-eslint/types": { |  | ||||||
|       "version": "7.13.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", |  | ||||||
|       "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", |  | ||||||
|       "dev": true, |  | ||||||
|       "engines": { |  | ||||||
|         "node": "^18.18.0 || >=20.0.0" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "type": "opencollective", |  | ||||||
|         "url": "https://opencollective.com/typescript-eslint" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/@typescript-eslint/typescript-estree": { |  | ||||||
|       "version": "7.13.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", |  | ||||||
|       "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", |  | ||||||
|       "dev": true, |  | ||||||
|       "dependencies": { |  | ||||||
|         "@typescript-eslint/types": "7.13.1", |  | ||||||
|         "@typescript-eslint/visitor-keys": "7.13.1", |  | ||||||
|         "debug": "^4.3.4", |  | ||||||
|         "globby": "^11.1.0", |  | ||||||
|         "is-glob": "^4.0.3", |  | ||||||
|         "minimatch": "^9.0.4", |  | ||||||
|         "semver": "^7.6.0", |  | ||||||
|         "ts-api-utils": "^1.3.0" |  | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": "^18.18.0 || >=20.0.0" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "type": "opencollective", |  | ||||||
|         "url": "https://opencollective.com/typescript-eslint" |  | ||||||
|       }, |  | ||||||
|       "peerDependenciesMeta": { |  | ||||||
|         "typescript": { |  | ||||||
|           "optional": true |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/@typescript-eslint/utils": { |  | ||||||
|       "version": "7.13.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", |  | ||||||
|       "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", |  | ||||||
|       "dev": true, |  | ||||||
|       "dependencies": { |  | ||||||
|         "@eslint-community/eslint-utils": "^4.4.0", |  | ||||||
|         "@typescript-eslint/scope-manager": "7.13.1", |  | ||||||
|         "@typescript-eslint/types": "7.13.1", |  | ||||||
|         "@typescript-eslint/typescript-estree": "7.13.1" |  | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": "^18.18.0 || >=20.0.0" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "type": "opencollective", |  | ||||||
|         "url": "https://opencollective.com/typescript-eslint" |  | ||||||
|       }, |  | ||||||
|       "peerDependencies": { |  | ||||||
|         "eslint": "^8.56.0" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/@typescript-eslint/visitor-keys": { |  | ||||||
|       "version": "7.13.1", |  | ||||||
|       "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", |  | ||||||
|       "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", |  | ||||||
|       "dev": true, |  | ||||||
|       "dependencies": { |  | ||||||
|         "@typescript-eslint/types": "7.13.1", |  | ||||||
|         "eslint-visitor-keys": "^3.4.3" |  | ||||||
|       }, |  | ||||||
|       "engines": { |  | ||||||
|         "node": "^18.18.0 || >=20.0.0" |  | ||||||
|       }, |  | ||||||
|       "funding": { |  | ||||||
|         "type": "opencollective", |  | ||||||
|         "url": "https://opencollective.com/typescript-eslint" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { |     "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { | ||||||
|       "version": "3.4.3", |       "version": "3.4.3", | ||||||
|       "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", |       "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", | ||||||
|       "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", |       "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|  |       "license": "Apache-2.0", | ||||||
|       "engines": { |       "engines": { | ||||||
|         "node": "^12.22.0 || ^14.17.0 || >=16.0.0" |         "node": "^12.22.0 || ^14.17.0 || >=16.0.0" | ||||||
|       }, |       }, | ||||||
| @@ -5513,6 +5431,22 @@ | |||||||
|         "eslint": ">=8.40.0" |         "eslint": ">=8.40.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/eslint-plugin-deprecation": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/eslint-plugin-deprecation/-/eslint-plugin-deprecation-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-JuVLdNg/uf0Adjg2tpTyYoYaMbwQNn/c78P1HcccokvhtRphgnRjZDKmhlxbxYptppex03zO76f97DD/yQHv7A==", | ||||||
|  |       "dev": true, | ||||||
|  |       "license": "LGPL-3.0-or-later", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@typescript-eslint/utils": "^7.0.0", | ||||||
|  |         "ts-api-utils": "^1.3.0", | ||||||
|  |         "tslib": "^2.3.1" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "eslint": "^8.0.0", | ||||||
|  |         "typescript": "^4.2.4 || ^5.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/eslint-plugin-escompat": { |     "node_modules/eslint-plugin-escompat": { | ||||||
|       "version": "3.4.0", |       "version": "3.4.0", | ||||||
|       "resolved": "https://registry.npmjs.org/eslint-plugin-escompat/-/eslint-plugin-escompat-3.4.0.tgz", |       "resolved": "https://registry.npmjs.org/eslint-plugin-escompat/-/eslint-plugin-escompat-3.4.0.tgz", | ||||||
|   | |||||||
| @@ -68,11 +68,13 @@ | |||||||
|     "@stoplight/spectral-cli": "6.11.1", |     "@stoplight/spectral-cli": "6.11.1", | ||||||
|     "@stylistic/eslint-plugin-js": "2.2.1", |     "@stylistic/eslint-plugin-js": "2.2.1", | ||||||
|     "@stylistic/stylelint-plugin": "2.1.2", |     "@stylistic/stylelint-plugin": "2.1.2", | ||||||
|  |     "@typescript-eslint/eslint-plugin": "7.14.1", | ||||||
|     "@typescript-eslint/parser": "7.14.1", |     "@typescript-eslint/parser": "7.14.1", | ||||||
|     "@vitejs/plugin-vue": "5.0.5", |     "@vitejs/plugin-vue": "5.0.5", | ||||||
|     "eslint": "8.57.0", |     "eslint": "8.57.0", | ||||||
|     "eslint-import-resolver-typescript": "3.6.1", |     "eslint-import-resolver-typescript": "3.6.1", | ||||||
|     "eslint-plugin-array-func": "4.0.0", |     "eslint-plugin-array-func": "4.0.0", | ||||||
|  |     "eslint-plugin-deprecation": "3.0.0", | ||||||
|     "eslint-plugin-github": "5.0.1", |     "eslint-plugin-github": "5.0.1", | ||||||
|     "eslint-plugin-i": "2.29.1", |     "eslint-plugin-i": "2.29.1", | ||||||
|     "eslint-plugin-no-jquery": "3.0.1", |     "eslint-plugin-no-jquery": "3.0.1", | ||||||
|   | |||||||
| @@ -7,21 +7,21 @@ test.beforeAll(async ({browser}, workerInfo) => { | |||||||
|  |  | ||||||
| test('homepage', async ({page}) => { | test('homepage', async ({page}) => { | ||||||
|   const response = await page.goto('/'); |   const response = await page.goto('/'); | ||||||
|   await expect(response?.status()).toBe(200); // Status OK |   expect(response?.status()).toBe(200); // Status OK | ||||||
|   await expect(page).toHaveTitle(/^Gitea: Git with a cup of tea\s*$/); |   await expect(page).toHaveTitle(/^Gitea: Git with a cup of tea\s*$/); | ||||||
|   await expect(page.locator('.logo')).toHaveAttribute('src', '/assets/img/logo.svg'); |   await expect(page.locator('.logo')).toHaveAttribute('src', '/assets/img/logo.svg'); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| test('register', async ({page}, workerInfo) => { | test('register', async ({page}, workerInfo) => { | ||||||
|   const response = await page.goto('/user/sign_up'); |   const response = await page.goto('/user/sign_up'); | ||||||
|   await expect(response?.status()).toBe(200); // Status OK |   expect(response?.status()).toBe(200); // Status OK | ||||||
|   await page.type('input[name=user_name]', `e2e-test-${workerInfo.workerIndex}`); |   await page.locator('input[name=user_name]').fill(`e2e-test-${workerInfo.workerIndex}`); | ||||||
|   await page.type('input[name=email]', `e2e-test-${workerInfo.workerIndex}@test.com`); |   await page.locator('input[name=email]').fill(`e2e-test-${workerInfo.workerIndex}@test.com`); | ||||||
|   await page.type('input[name=password]', 'test123test123'); |   await page.locator('input[name=password]').fill('test123test123'); | ||||||
|   await page.type('input[name=retype]', 'test123test123'); |   await page.locator('input[name=retype]').fill('test123test123'); | ||||||
|   await page.click('form button.ui.primary.button:visible'); |   await page.click('form button.ui.primary.button:visible'); | ||||||
|   // Make sure we routed to the home page. Else login failed. |   // Make sure we routed to the home page. Else login failed. | ||||||
|   await expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`); |   expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`); | ||||||
|   await expect(page.locator('.secondary-nav span>img.ui.avatar')).toBeVisible(); |   await expect(page.locator('.secondary-nav span>img.ui.avatar')).toBeVisible(); | ||||||
|   await expect(page.locator('.ui.positive.message.flash-success')).toHaveText('Account was successfully created. Welcome!'); |   await expect(page.locator('.ui.positive.message.flash-success')).toHaveText('Account was successfully created. Welcome!'); | ||||||
|  |  | ||||||
| @@ -30,15 +30,15 @@ test('register', async ({page}, workerInfo) => { | |||||||
|  |  | ||||||
| test('login', async ({page}, workerInfo) => { | test('login', async ({page}, workerInfo) => { | ||||||
|   const response = await page.goto('/user/login'); |   const response = await page.goto('/user/login'); | ||||||
|   await expect(response?.status()).toBe(200); // Status OK |   expect(response?.status()).toBe(200); // Status OK | ||||||
|  |  | ||||||
|   await page.type('input[name=user_name]', `user2`); |   await page.locator('input[name=user_name]').fill(`user2`); | ||||||
|   await page.type('input[name=password]', `password`); |   await page.locator('input[name=password]').fill(`password`); | ||||||
|   await page.click('form button.ui.primary.button:visible'); |   await page.click('form button.ui.primary.button:visible'); | ||||||
|  |  | ||||||
|   await page.waitForLoadState('networkidle'); // eslint-disable-line playwright/no-networkidle |   await page.waitForLoadState('networkidle'); // eslint-disable-line playwright/no-networkidle | ||||||
|  |  | ||||||
|   await expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`); |   expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`); | ||||||
|  |  | ||||||
|   save_visual(page); |   save_visual(page); | ||||||
| }); | }); | ||||||
| @@ -50,7 +50,7 @@ test('logged in user', async ({browser}, workerInfo) => { | |||||||
|   await page.goto('/'); |   await page.goto('/'); | ||||||
|  |  | ||||||
|   // Make sure we routed to the home page. Else login failed. |   // Make sure we routed to the home page. Else login failed. | ||||||
|   await expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`); |   expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`); | ||||||
|  |  | ||||||
|   save_visual(page); |   save_visual(page); | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ export async function login_user(browser, workerInfo, user) { | |||||||
|   // Route to login page |   // Route to login page | ||||||
|   // Note: this could probably be done more quickly with a POST |   // Note: this could probably be done more quickly with a POST | ||||||
|   const response = await page.goto('/user/login'); |   const response = await page.goto('/user/login'); | ||||||
|   await expect(response?.status()).toBe(200); // Status OK |   expect(response?.status()).toBe(200); // Status OK | ||||||
|  |  | ||||||
|   // Fill out form |   // Fill out form | ||||||
|   await page.type('input[name=user_name]', user); |   await page.type('input[name=user_name]', user); | ||||||
| @@ -23,7 +23,7 @@ export async function login_user(browser, workerInfo, user) { | |||||||
|  |  | ||||||
|   await page.waitForLoadState('networkidle'); // eslint-disable-line playwright/no-networkidle |   await page.waitForLoadState('networkidle'); // eslint-disable-line playwright/no-networkidle | ||||||
|  |  | ||||||
|   await expect(page.url(), {message: `Failed to login user ${user}`}).toBe(`${workerInfo.project.use.baseURL}/`); |   expect(page.url(), {message: `Failed to login user ${user}`}).toBe(`${workerInfo.project.use.baseURL}/`); | ||||||
|  |  | ||||||
|   // Save state |   // Save state | ||||||
|   await context.storageState({path: `${ARTIFACTS_PATH}/state-${user}-${workerInfo.workerIndex}.json`}); |   await context.storageState({path: `${ARTIFACTS_PATH}/state-${user}-${workerInfo.workerIndex}.json`}); | ||||||
|   | |||||||
| @@ -89,7 +89,9 @@ const sfc = { | |||||||
|     // load job data and then auto-reload periodically |     // load job data and then auto-reload periodically | ||||||
|     // need to await first loadJob so this.currentJobStepsStates is initialized and can be used in hashChangeListener |     // need to await first loadJob so this.currentJobStepsStates is initialized and can be used in hashChangeListener | ||||||
|     await this.loadJob(); |     await this.loadJob(); | ||||||
|     this.intervalID = setInterval(this.loadJob, 1000); |     this.intervalID = setInterval(() => { | ||||||
|  |       this.loadJob(); | ||||||
|  |     }, 1000); | ||||||
|     document.body.addEventListener('click', this.closeDropdown); |     document.body.addEventListener('click', this.closeDropdown); | ||||||
|     this.hashChangeListener(); |     this.hashChangeListener(); | ||||||
|     window.addEventListener('hashchange', this.hashChangeListener); |     window.addEventListener('hashchange', this.hashChangeListener); | ||||||
|   | |||||||
| @@ -153,7 +153,7 @@ export function initRepoCodeView() { | |||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     $(window).on('hashchange', () => { |     $(window).on('hashchange', () => { | ||||||
|       let m = rangeAnchorRegex.exec(window.location.hash.match); |       let m = rangeAnchorRegex.exec(window.location.hash); | ||||||
|       const $linesEls = $(getLineEls()); |       const $linesEls = $(getLineEls()); | ||||||
|       let $first; |       let $first; | ||||||
|       if (m) { |       if (m) { | ||||||
| @@ -170,7 +170,7 @@ export function initRepoCodeView() { | |||||||
|           return; |           return; | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       m = singleAnchorRegex.exec(window.location.hash.match); |       m = singleAnchorRegex.exec(window.location.hash); | ||||||
|       if (m) { |       if (m) { | ||||||
|         $first = $linesEls.filter(`[rel=L${m[2]}]`); |         $first = $linesEls.filter(`[rel=L${m[2]}]`); | ||||||
|         if ($first.length) { |         if ($first.length) { | ||||||
|   | |||||||
| @@ -55,8 +55,8 @@ export function filterRepoFilesWeighted(files, filter) { | |||||||
|     const filterLower = filter.toLowerCase(); |     const filterLower = filter.toLowerCase(); | ||||||
|     // TODO: for large repo, this loop could be slow, maybe there could be one more limit: |     // TODO: for large repo, this loop could be slow, maybe there could be one more limit: | ||||||
|     // ... && filterResult.length < threshold * 20,  wait for more feedbacks |     // ... && filterResult.length < threshold * 20,  wait for more feedbacks | ||||||
|     for (let i = 0; i < files.length; i++) { |     for (const file of files) { | ||||||
|       const res = strSubMatch(files[i], filterLower); |       const res = strSubMatch(file, filterLower); | ||||||
|       if (res.length > 1) { // length==1 means unmatched, >1 means having matched sub strings |       if (res.length > 1) { // length==1 means unmatched, >1 means having matched sub strings | ||||||
|         filterResult.push({matchResult: res, matchWeight: calcMatchedWeight(res)}); |         filterResult.push({matchResult: res, matchWeight: calcMatchedWeight(res)}); | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -102,16 +102,16 @@ export function initRepoTopicBar() { | |||||||
|  |  | ||||||
|         if (res.topics) { |         if (res.topics) { | ||||||
|           let found = false; |           let found = false; | ||||||
|           for (let i = 0; i < res.topics.length; i++) { |           for (const {topic_name} of res.topics) { | ||||||
|             // skip currently added tags |             // skip currently added tags | ||||||
|             if (current_topics.includes(res.topics[i].topic_name)) { |             if (current_topics.includes(topic_name)) { | ||||||
|               continue; |               continue; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (res.topics[i].topic_name.toLowerCase() === query.toLowerCase()) { |             if (topic_name.toLowerCase() === query.toLowerCase()) { | ||||||
|               found_query = true; |               found_query = true; | ||||||
|             } |             } | ||||||
|             formattedResponse.results.push({description: res.topics[i].topic_name, 'data-value': res.topics[i].topic_name}); |             formattedResponse.results.push({description: topic_name, 'data-value': topic_name}); | ||||||
|             found = true; |             found = true; | ||||||
|           } |           } | ||||||
|           formattedResponse.success = found; |           formattedResponse.success = found; | ||||||
|   | |||||||
| @@ -270,7 +270,7 @@ export function replaceTextareaSelection(textarea, text) { | |||||||
|  |  | ||||||
|   textarea.contentEditable = 'true'; |   textarea.contentEditable = 'true'; | ||||||
|   try { |   try { | ||||||
|     success = document.execCommand('insertText', false, text); |     success = document.execCommand('insertText', false, text); // eslint-disable-line deprecation/deprecation | ||||||
|   } catch { |   } catch { | ||||||
|     success = false; |     success = false; | ||||||
|   } |   } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user