Parcourir la source

chore(lint): enforce JavaScript checks consistently

Co-authored-by: Cursor <cursoragent@cursor.com>
jamesread il y a 14 heures
Parent
commit
4c6b6ac0fe
28 fichiers modifiés avec 136 ajouts et 84 suppressions
  1. 7 6
      frontend/Makefile
  2. 2 0
      frontend/package.json
  3. 12 12
      frontend/vite.config.mjs
  4. 0 8
      integration-tests/.eslintrc.yml
  5. 9 3
      integration-tests/Makefile
  6. 31 0
      integration-tests/eslint.config.mjs
  7. 1 1
      integration-tests/lib/elements.js
  8. 36 0
      integration-tests/package-lock.json
  9. 5 1
      integration-tests/package.json
  10. 1 1
      integration-tests/scripts/find-flakey-tests-inf.mjs
  11. 1 1
      integration-tests/tests/argumentActionFlash/argumentActionFlash.mjs
  12. 1 1
      integration-tests/tests/argumentIdCollision/argumentIdCollision.mjs
  13. 1 2
      integration-tests/tests/authRequireGuestsToLogin/authRequireGuestsToLogin.mjs
  14. 1 1
      integration-tests/tests/checkbox/checkbox.mjs
  15. 1 1
      integration-tests/tests/checklist/checklist.mjs
  16. 1 1
      integration-tests/tests/confirmation/confirmation.mjs
  17. 1 1
      integration-tests/tests/dashboardsWithBasicFieldsets/dashboardsWithBasicFieldsets.mjs
  18. 0 1
      integration-tests/tests/emptyDashboardsAreHidden/emptyDashboardsAreHidden.mjs
  19. 1 3
      integration-tests/tests/hiddenFooter/hiddenFooter.mjs
  20. 2 5
      integration-tests/tests/hiddenNav/hiddenNav.mjs
  21. 1 1
      integration-tests/tests/justification/justification.mjs
  22. 5 6
      integration-tests/tests/localAuth/localAuth.mjs
  23. 1 2
      integration-tests/tests/logPersistence/logPersistence.mjs
  24. 1 1
      integration-tests/tests/multipleDropdowns/multipleDropdowns.mjs
  25. 8 15
      integration-tests/tests/oauthLoginGithub/githubOAuth.mjs
  26. 1 2
      integration-tests/tests/onlyDashboards/onlyDashboards.mjs
  27. 1 3
      integration-tests/tests/sleep/sleep.mjs
  28. 4 5
      integration-tests/tests/stdoutMostRecentExecution/stdoutMostRecentExecution.mjs

+ 7 - 6
frontend/Makefile

@@ -2,10 +2,11 @@ define delete-files
 	python3 -c "import shutil;shutil.rmtree('$(1)', ignore_errors=True)"
 	python3 -c "import shutil;shutil.rmtree('$(1)', ignore_errors=True)"
 endef
 endef
 
 
-codestyle:
-	npm install
-	npx eslint --fix main.js js/* resources/vue
-	npx stylelint style.css
+codestyle: deps
+	npm run lint
+
+codestyle-fix: deps
+	npm run lint:fix
 
 
 unittests: deps
 unittests: deps
 	npm test
 	npm test
@@ -14,11 +15,11 @@ clean:
 	$(call delete-files,dist)
 	$(call delete-files,dist)
 
 
 deps:
 deps:
-	npm install
+	npm ci
 
 
 build:
 build:
 	npx vite build
 	npx vite build
 
 
 dist: deps clean build
 dist: deps clean build
 
 
-.PHONY: codestyle unittests
+.PHONY: codestyle codestyle-fix unittests deps build dist clean

+ 2 - 0
frontend/package.json

@@ -11,6 +11,8 @@
 		"stylelint-config-standard": "^40.0.0"
 		"stylelint-config-standard": "^40.0.0"
 	},
 	},
 	"scripts": {
 	"scripts": {
+		"lint": "eslint main.js js/* resources/vue vite.config.mjs && stylelint \"style.css\" \"themes/**/*.css\"",
+		"lint:fix": "eslint --fix main.js js/* resources/vue vite.config.mjs && stylelint --fix \"style.css\" \"themes/**/*.css\"",
 		"test": "node --test resources/vue/components/*.test.mjs resources/vue/utils/*.test.mjs resources/vue/stores/*.test.mjs"
 		"test": "node --test resources/vue/components/*.test.mjs resources/vue/utils/*.test.mjs resources/vue/stores/*.test.mjs"
 	},
 	},
 	"author": "",
 	"author": "",

+ 12 - 12
frontend/vite.config.mjs

@@ -4,16 +4,16 @@ import Components from 'unplugin-vue-components/vite'
 
 
 export default defineConfig({
 export default defineConfig({
   resolve: {
   resolve: {
-    dedupe: ['vue', 'vue-router'],
+    dedupe: ['vue', 'vue-router']
   },
   },
   plugins: [
   plugins: [
     Components({
     Components({
       dirs: ['resources/vue/'],
       dirs: ['resources/vue/'],
       extensions: ['vue'],
       extensions: ['vue'],
       deep: true,
       deep: true,
-      dts: false,
+      dts: false
     }),
     }),
-    vue(),
+    vue()
   ],
   ],
   build: {
   build: {
     rolldownOptions: {
     rolldownOptions: {
@@ -22,25 +22,25 @@ export default defineConfig({
           return
           return
         }
         }
         defaultHandler(level, log)
         defaultHandler(level, log)
-      },
-    },
+      }
+    }
   },
   },
   server: {
   server: {
     proxy: {
     proxy: {
       '/api': {
       '/api': {
         target: 'http://localhost:1337',
         target: 'http://localhost:1337',
         changeOrigin: true,
         changeOrigin: true,
-        secure: false,
+        secure: false
       },
       },
       '/theme.css': {
       '/theme.css': {
         target: 'http://localhost:1337',
         target: 'http://localhost:1337',
         changeOrigin: true,
         changeOrigin: true,
-        secure: false,
+        secure: false
       },
       },
-      "/custom-webui": {
-        target: "http://localhost:1337",
-        changeOrigin: true,
+      '/custom-webui': {
+        target: 'http://localhost:1337',
+        changeOrigin: true
       }
       }
-    },
-  },
+    }
+  }
 })
 })

+ 0 - 8
integration-tests/.eslintrc.yml

@@ -1,8 +0,0 @@
-env:
-  browser: true
-  es2021: true
-extends: 'eslint:recommended'
-parserOptions:
-  ecmaVersion: 12
-  sourceType: module
-rules: {}

+ 9 - 3
integration-tests/Makefile

@@ -1,7 +1,13 @@
 default: test-install prep test-run
 default: test-install prep test-run
 
 
 test-install:
 test-install:
-	npm install --no-fund
+	npm ci --no-fund
+
+codestyle: test-install
+	npm run lint
+
+codestyle-fix: test-install
+	npm run lint:fix
 
 
 prep:
 prep:
 ifneq ($(SKIP_WEBUI),1)
 ifneq ($(SKIP_WEBUI),1)
@@ -11,7 +17,7 @@ endif
 
 
 test-run:
 test-run:
     # GitHub Actions fails badly on the default timeout of 2000ms
     # GitHub Actions fails badly on the default timeout of 2000ms
-	npx mocha tests --recursive -t 10000
+	npm test
 
 
 find-flakey-tests:
 find-flakey-tests:
 	echo "Running test-run infinately"
 	echo "Running test-run infinately"
@@ -30,4 +36,4 @@ getsnapshot:
 	rm -rf /opt/OliveTin-snapshot/*
 	rm -rf /opt/OliveTin-snapshot/*
 	gh run download -D /opt/OliveTin-snapshot/
 	gh run download -D /opt/OliveTin-snapshot/
 
 
-.PHONY: default find-flakey-tests find-flakey-tests-inf prep
+.PHONY: default test-install codestyle codestyle-fix test-run find-flakey-tests find-flakey-tests-inf prep

+ 31 - 0
integration-tests/eslint.config.mjs

@@ -0,0 +1,31 @@
+import js from '@eslint/js'
+import globals from 'globals'
+
+export default [
+  {
+    ignores: [
+      'node_modules/**',
+      'tests/customJs/custom-webui/**'
+    ]
+  },
+  js.configs.recommended,
+  {
+    files: ['**/*.{js,mjs}'],
+    languageOptions: {
+      ecmaVersion: 'latest',
+      sourceType: 'module',
+      globals: {
+        ...globals.browser,
+        ...globals.node,
+        after: 'readonly',
+        afterEach: 'readonly',
+        before: 'readonly',
+        beforeEach: 'readonly',
+        describe: 'readonly',
+        it: 'readonly',
+        runner: 'readonly',
+        webdriver: 'readonly'
+      }
+    }
+  }
+]

+ 1 - 1
integration-tests/lib/elements.js

@@ -114,7 +114,7 @@ export function takeScreenshot (webdriver, title) {
     fs.mkdirSync('screenshots', { recursive: true });
     fs.mkdirSync('screenshots', { recursive: true });
 
 
   title = title.replaceAll('config: ', '')
   title = title.replaceAll('config: ', '')
-	title = title.replaceAll(/[\(\)\|\*\<\>\:]/g, "_")
+	title = title.replaceAll(/[()|*<>:]/g, '_')
 	title = title + '.failed-test'
 	title = title + '.failed-test'
 
 
     fs.writeFileSync('screenshots/' + title + '.png', img, 'base64')
     fs.writeFileSync('screenshots/' + title + '.png', img, 'base64')

+ 36 - 0
integration-tests/package-lock.json

@@ -12,8 +12,10 @@
         "wait-on": "^9.1.0"
         "wait-on": "^9.1.0"
       },
       },
       "devDependencies": {
       "devDependencies": {
+        "@eslint/js": "^10.0.1",
         "chai": "^6.2.2",
         "chai": "^6.2.2",
         "eslint": "^10.10.0",
         "eslint": "^10.10.0",
+        "globals": "^17.3.0",
         "mocha": "^12.0.0",
         "mocha": "^12.0.0",
         "selenium-webdriver": "^4.49.0"
         "selenium-webdriver": "^4.49.0"
       }
       }
@@ -141,6 +143,27 @@
         "node": "^20.19.0 || ^22.13.0 || >=24"
         "node": "^20.19.0 || ^22.13.0 || >=24"
       }
       }
     },
     },
+    "node_modules/@eslint/js": {
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz",
+      "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^20.19.0 || ^22.13.0 || >=24"
+      },
+      "funding": {
+        "url": "https://eslint.org/donate"
+      },
+      "peerDependencies": {
+        "eslint": "^10.0.0"
+      },
+      "peerDependenciesMeta": {
+        "eslint": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@eslint/object-schema": {
     "node_modules/@eslint/object-schema": {
       "version": "3.0.5",
       "version": "3.0.5",
       "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz",
       "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz",
@@ -966,6 +989,19 @@
         "node": ">=10.13.0"
         "node": ">=10.13.0"
       }
       }
     },
     },
+    "node_modules/globals": {
+      "version": "17.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-17.12.0.tgz",
+      "integrity": "sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/gopd": {
     "node_modules/gopd": {
       "version": "1.2.0",
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
       "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",

+ 5 - 1
integration-tests/package.json

@@ -6,13 +6,17 @@
   "main": "index.js",
   "main": "index.js",
   "type": "module",
   "type": "module",
   "scripts": {
   "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
+    "lint": "eslint tests lib scripts runner.mjs mochaSetup.mjs",
+    "lint:fix": "npm run lint -- --fix",
+    "test": "mocha tests --recursive -t 10000"
   },
   },
   "author": "",
   "author": "",
   "license": "AGPL-3.0-only",
   "license": "AGPL-3.0-only",
   "devDependencies": {
   "devDependencies": {
+    "@eslint/js": "^10.0.1",
     "chai": "^6.2.2",
     "chai": "^6.2.2",
     "eslint": "^10.10.0",
     "eslint": "^10.10.0",
+    "globals": "^17.3.0",
     "mocha": "^12.0.0",
     "mocha": "^12.0.0",
     "selenium-webdriver": "^4.49.0"
     "selenium-webdriver": "^4.49.0"
   },
   },

+ 1 - 1
integration-tests/scripts/find-flakey-tests-inf.mjs

@@ -104,7 +104,7 @@ function runMochaOnce () {
       try {
       try {
         report = JSON.parse(readFileSync(reportPath, 'utf8'))
         report = JSON.parse(readFileSync(reportPath, 'utf8'))
       } catch {
       } catch {
-        report = null
+        // Keep the default null report when Mocha did not produce valid JSON.
       }
       }
 
 
       try {
       try {

+ 1 - 1
integration-tests/tests/argumentActionFlash/argumentActionFlash.mjs

@@ -28,7 +28,7 @@ async function waitForActionSuccessFlash (actionTitle) {
         const button = await getActionButton(webdriver, actionTitle)
         const button = await getActionButton(webdriver, actionTitle)
         const classAttr = await button.getAttribute('class')
         const classAttr = await button.getAttribute('class')
         return classAttr && classAttr.includes('action-success')
         return classAttr && classAttr.includes('action-success')
-      } catch (e) {
+      } catch {
         return false
         return false
       }
       }
     }),
     }),

+ 1 - 1
integration-tests/tests/argumentIdCollision/argumentIdCollision.mjs

@@ -45,7 +45,7 @@ async function waitForTerminalOutput (expectedSubstring) {
 
 
         const output = await getTerminalBuffer()
         const output = await getTerminalBuffer()
         return output && output.includes(expectedSubstring)
         return output && output.includes(expectedSubstring)
-      } catch (e) {
+      } catch {
         return false
         return false
       }
       }
     }),
     }),

+ 1 - 2
integration-tests/tests/authRequireGuestsToLogin/authRequireGuestsToLogin.mjs

@@ -1,8 +1,7 @@
 import { describe, it, before, after } from 'mocha'
 import { describe, it, before, after } from 'mocha'
 import { expect } from 'chai'
 import { expect } from 'chai'
-import { By, until } from 'selenium-webdriver'
+import { By } from 'selenium-webdriver'
 import {
 import {
-  getRootAndWait,
   takeScreenshotOnFailure,
   takeScreenshotOnFailure,
 } from '../../lib/elements.js'
 } from '../../lib/elements.js'
 
 

+ 1 - 1
integration-tests/tests/checkbox/checkbox.mjs

@@ -47,7 +47,7 @@ async function waitForTerminalOutput(expectedValue) {
         }
         }
 
 
         return output.trim().includes(`Checkbox value: ${expectedValue}`)
         return output.trim().includes(`Checkbox value: ${expectedValue}`)
-      } catch (e) {
+      } catch {
         return false
         return false
       }
       }
     }),
     }),

+ 1 - 1
integration-tests/tests/checklist/checklist.mjs

@@ -44,7 +44,7 @@ async function pollTerminal(matcher, timeoutMs = DEFAULT_UI_WAIT_MS) {
         }
         }
 
 
         return matcher(output.trim())
         return matcher(output.trim())
-      } catch (e) {
+      } catch {
         return false
         return false
       }
       }
     }),
     }),

+ 1 - 1
integration-tests/tests/confirmation/confirmation.mjs

@@ -59,7 +59,7 @@ async function waitForTerminalOutput (expectedSubstring) {
 
 
         const output = await getTerminalBuffer()
         const output = await getTerminalBuffer()
         return output && output.includes(expectedSubstring)
         return output && output.includes(expectedSubstring)
-      } catch (e) {
+      } catch {
         return false
         return false
       }
       }
     }),
     }),

+ 1 - 1
integration-tests/tests/dashboardsWithBasicFieldsets/dashboardsWithBasicFieldsets.mjs

@@ -1,6 +1,6 @@
 import { describe, it, before, after } from 'mocha'
 import { describe, it, before, after } from 'mocha'
 import { expect, assert } from 'chai'
 import { expect, assert } from 'chai'
-import { By, until, Condition } from 'selenium-webdriver'
+import { By } from 'selenium-webdriver'
 //import * as waitOn from 'wait-on'
 //import * as waitOn from 'wait-on'
 import {
 import {
   getRootAndWait,
   getRootAndWait,

+ 0 - 1
integration-tests/tests/emptyDashboardsAreHidden/emptyDashboardsAreHidden.mjs

@@ -1,6 +1,5 @@
 import { describe, it, before, after } from 'mocha'
 import { describe, it, before, after } from 'mocha'
 import { expect } from 'chai'
 import { expect } from 'chai'
-import { By, until, Condition } from 'selenium-webdriver'
 //import * as waitOn from 'wait-on'
 //import * as waitOn from 'wait-on'
 import {
 import {
   getRootAndWait,
   getRootAndWait,

+ 1 - 3
integration-tests/tests/hiddenFooter/hiddenFooter.mjs

@@ -2,9 +2,7 @@ import { describe, it, before, after } from 'mocha'
 import { expect } from 'chai'
 import { expect } from 'chai'
 
 
 import { By } from 'selenium-webdriver'
 import { By } from 'selenium-webdriver'
-import { 
-  getRootAndWait, 
-  getActionButtons,
+import {
   takeScreenshotOnFailure,
   takeScreenshotOnFailure,
 } from '../../lib/elements.js'
 } from '../../lib/elements.js'
 
 

+ 2 - 5
integration-tests/tests/hiddenNav/hiddenNav.mjs

@@ -1,8 +1,5 @@
-import { expect } from 'chai'
-import { By } from 'selenium-webdriver'
-import { 
-  getRootAndWait, 
-  getActionButtons,
+import {
+  getRootAndWait,
   takeScreenshotOnFailure,
   takeScreenshotOnFailure,
 } from '../../lib/elements.js'
 } from '../../lib/elements.js'
 
 

+ 1 - 1
integration-tests/tests/justification/justification.mjs

@@ -88,7 +88,7 @@ async function waitForTerminalOutput (expectedSubstring) {
 
 
         const output = await getTerminalBuffer()
         const output = await getTerminalBuffer()
         return output && output.includes(expectedSubstring)
         return output && output.includes(expectedSubstring)
-      } catch (e) {
+      } catch {
         return false
         return false
       }
       }
     }),
     }),

+ 5 - 6
integration-tests/tests/localAuth/localAuth.mjs

@@ -1,8 +1,7 @@
 import { describe, it, before, after } from 'mocha'
 import { describe, it, before, after } from 'mocha'
 import { expect } from 'chai'
 import { expect } from 'chai'
-import { By, until, Condition } from 'selenium-webdriver'
+import { By, until } from 'selenium-webdriver'
 import {
 import {
-  getRootAndWait,
   takeScreenshotOnFailure,
   takeScreenshotOnFailure,
 } from '../../lib/elements.js'
 } from '../../lib/elements.js'
 
 
@@ -47,7 +46,7 @@ describe('config: localAuth', function () {
     // Check if any login-related elements are present
     // Check if any login-related elements are present
     const bodyText = await webdriver.findElement(By.tagName('body')).getText()
     const bodyText = await webdriver.findElement(By.tagName('body')).getText()
     console.log('Login page content:', bodyText.substring(0, 300))
     console.log('Login page content:', bodyText.substring(0, 300))
-    
+
     // For now, just verify we can navigate to the login page
     // For now, just verify we can navigate to the login page
     // The page content rendering is a separate frontend issue
     // The page content rendering is a separate frontend issue
     console.log('Login page navigation successful')
     console.log('Login page navigation successful')
@@ -67,11 +66,11 @@ describe('config: localAuth', function () {
 
 
     if (usernameFields.length > 0 && passwordFields.length > 0 && loginButtons.length > 0) {
     if (usernameFields.length > 0 && passwordFields.length > 0 && loginButtons.length > 0) {
       console.log('Login form found, attempting login')
       console.log('Login form found, attempting login')
-      
+
       // Fill in credentials
       // Fill in credentials
       await usernameFields[0].clear()
       await usernameFields[0].clear()
       await usernameFields[0].sendKeys('testuser')
       await usernameFields[0].sendKeys('testuser')
-      
+
       await passwordFields[0].clear()
       await passwordFields[0].clear()
       await passwordFields[0].sendKeys('testpass123')
       await passwordFields[0].sendKeys('testpass123')
 
 
@@ -100,4 +99,4 @@ describe('config: localAuth', function () {
       console.log('Login form not found - skipping login test')
       console.log('Login form not found - skipping login test')
     }
     }
   })
   })
-})
+})

+ 1 - 2
integration-tests/tests/logPersistence/logPersistence.mjs

@@ -5,7 +5,6 @@ import fs from 'fs'
 import path from 'path'
 import path from 'path'
 import {
 import {
   getRootAndWait,
   getRootAndWait,
-  getActionButtons,
   takeScreenshotOnFailure,
   takeScreenshotOnFailure,
 } from '../../lib/elements.js'
 } from '../../lib/elements.js'
 
 
@@ -210,7 +209,7 @@ describe('config: logPersistence', function () {
           const text = await body.getText()
           const text = await body.getText()
           // The log should contain the output from the echo command
           // The log should contain the output from the echo command
           return text.includes('Hello from persisted log test') || text.includes(firstExecutionTrackingId)
           return text.includes('Hello from persisted log test') || text.includes(firstExecutionTrackingId)
-        } catch (e) {
+        } catch {
           return false
           return false
         }
         }
       }),
       }),

+ 1 - 1
integration-tests/tests/multipleDropdowns/multipleDropdowns.mjs

@@ -1,6 +1,6 @@
 import { describe, it, before, after } from 'mocha'
 import { describe, it, before, after } from 'mocha'
 import { expect } from 'chai'
 import { expect } from 'chai'
-import { By, until, Condition, Key } from 'selenium-webdriver'
+import { By, Condition, Key } from 'selenium-webdriver'
 import {
 import {
   getRootAndWait,
   getRootAndWait,
   getActionButtons,
   getActionButtons,

+ 8 - 15
integration-tests/tests/oauthLoginGithub/githubOAuth.mjs

@@ -1,8 +1,7 @@
 import { describe, it, before, after } from 'mocha'
 import { describe, it, before, after } from 'mocha'
 import { expect } from 'chai'
 import { expect } from 'chai'
-import { By, until, Condition } from 'selenium-webdriver'
+import { By, until } from 'selenium-webdriver'
 import {
 import {
-  getRootAndWait,
   takeScreenshotOnFailure,
   takeScreenshotOnFailure,
 } from '../../lib/elements.js'
 } from '../../lib/elements.js'
 
 
@@ -56,14 +55,14 @@ describe('config: githubOAuth', function () {
     // Button may show "Login with GitHub" or "Login with undefined" depending on provider.name vs provider.title
     // Button may show "Login with GitHub" or "Login with undefined" depending on provider.name vs provider.title
     // We'll check for the presence of the button and verify it's in the OAuth section
     // We'll check for the presence of the button and verify it's in the OAuth section
     expect(githubButtons.length).to.be.greaterThan(0, 'At least one OAuth button should be present')
     expect(githubButtons.length).to.be.greaterThan(0, 'At least one OAuth button should be present')
-    
+
     // The first button should be GitHub since it's the only provider in the config
     // The first button should be GitHub since it's the only provider in the config
     const githubButton = githubButtons[0]
     const githubButton = githubButtons[0]
     const buttonText = await githubButton.getText()
     const buttonText = await githubButton.getText()
-    
+
     // Button should contain "Login with" and the provider should be configured as GitHub
     // Button should contain "Login with" and the provider should be configured as GitHub
     expect(buttonText).to.include('Login with', 'Button should have "Login with" prefix')
     expect(buttonText).to.include('Login with', 'Button should have "Login with" prefix')
-    
+
     console.log('GitHub OAuth button found with text:', buttonText)
     console.log('GitHub OAuth button found with text:', buttonText)
   })
   })
 
 
@@ -78,16 +77,14 @@ describe('config: githubOAuth', function () {
     // Since the test config only has one provider (GitHub), we can use the first button
     // Since the test config only has one provider (GitHub), we can use the first button
     const githubButtons = await webdriver.findElements(By.css('.oauth-button'))
     const githubButtons = await webdriver.findElements(By.css('.oauth-button'))
     expect(githubButtons.length).to.be.greaterThan(0, 'At least one OAuth button should be present')
     expect(githubButtons.length).to.be.greaterThan(0, 'At least one OAuth button should be present')
-    
+
     const githubButton = githubButtons[0]
     const githubButton = githubButtons[0]
     const buttonText = await githubButton.getText()
     const buttonText = await githubButton.getText()
     console.log('Button text:', buttonText)
     console.log('Button text:', buttonText)
-    
+
     // Verify it's the GitHub button (should contain "github" in the text)
     // Verify it's the GitHub button (should contain "github" in the text)
     expect(buttonText.toLowerCase()).to.include('github', 'Button should be GitHub OAuth button')
     expect(buttonText.toLowerCase()).to.include('github', 'Button should be GitHub OAuth button')
 
 
-    // Check for provider icon (if present)
-    const providerIcons = await githubButton.findElements(By.css('.provider-icon'))
     const providerNames = await githubButton.findElements(By.css('.provider-name'))
     const providerNames = await githubButton.findElements(By.css('.provider-name'))
     // Provider name may show "GitHub" (from title) or be undefined (if using name field)
     // Provider name may show "GitHub" (from title) or be undefined (if using name field)
     // Just verify the structure is present
     // Just verify the structure is present
@@ -111,11 +108,8 @@ describe('config: githubOAuth', function () {
     // Find GitHub OAuth button (should be the first/only one in our test config)
     // Find GitHub OAuth button (should be the first/only one in our test config)
     const githubButtons = await webdriver.findElements(By.css('.oauth-button'))
     const githubButtons = await webdriver.findElements(By.css('.oauth-button'))
     expect(githubButtons.length).to.be.greaterThan(0, 'OAuth button should be present')
     expect(githubButtons.length).to.be.greaterThan(0, 'OAuth button should be present')
-    
-    const githubButton = githubButtons[0]
 
 
-    // Get the current URL before clicking
-    const initialUrl = await webdriver.getCurrentUrl()
+    const githubButton = githubButtons[0]
 
 
     // Click the button
     // Click the button
     await githubButton.click()
     await githubButton.click()
@@ -124,7 +118,7 @@ describe('config: githubOAuth', function () {
     // Since we can't actually complete OAuth flow, we check that the button
     // Since we can't actually complete OAuth flow, we check that the button
     // click handler is set up correctly by verifying the button exists and is clickable
     // click handler is set up correctly by verifying the button exists and is clickable
     // In a real scenario, this would redirect to GitHub's OAuth page
     // In a real scenario, this would redirect to GitHub's OAuth page
-    
+
     // Give a small delay to allow any navigation to start
     // Give a small delay to allow any navigation to start
     await new Promise(resolve => setTimeout(resolve, 1000))
     await new Promise(resolve => setTimeout(resolve, 1000))
 
 
@@ -133,4 +127,3 @@ describe('config: githubOAuth', function () {
     console.log('GitHub OAuth button click verified (redirect would happen in production)')
     console.log('GitHub OAuth button click verified (redirect would happen in production)')
   })
   })
 })
 })
-

+ 1 - 2
integration-tests/tests/onlyDashboards/onlyDashboards.mjs

@@ -6,7 +6,6 @@ import {
   getActionButtons,
   getActionButtons,
   getNavigationLinks,
   getNavigationLinks,
   openSidebar,
   openSidebar,
-  closeSidebar,
   takeScreenshotOnFailure,
   takeScreenshotOnFailure,
 } from '../../lib/elements.js'
 } from '../../lib/elements.js'
 
 
@@ -43,7 +42,7 @@ describe('config: onlyDashboards', function () {
     const firstDashboardLink = await webdriver.findElement(By.css('li[title="My Dashboard"]'), 'The first dashboard link should be present')
     const firstDashboardLink = await webdriver.findElement(By.css('li[title="My Dashboard"]'), 'The first dashboard link should be present')
     assert.isNotNull(firstDashboardLink, 'First dashboard link should not be null')
     assert.isNotNull(firstDashboardLink, 'First dashboard link should not be null')
     assert.isTrue(await firstDashboardLink.isDisplayed(), 'First dashboard link should be displayed')
     assert.isTrue(await firstDashboardLink.isDisplayed(), 'First dashboard link should be displayed')
-    
+
     const actionButtonsOnDashboard = await getActionButtons()
     const actionButtonsOnDashboard = await getActionButtons()
     assert.isArray(actionButtonsOnDashboard, 'Action buttons on dashboard should be an array')
     assert.isArray(actionButtonsOnDashboard, 'Action buttons on dashboard should be an array')
     assert.lengthOf(actionButtonsOnDashboard, 3, 'Action buttons on dashboard should have 3 buttons')
     assert.lengthOf(actionButtonsOnDashboard, 3, 'Action buttons on dashboard should have 3 buttons')

+ 1 - 3
integration-tests/tests/sleep/sleep.mjs

@@ -1,9 +1,7 @@
-import * as process from 'node:process'
 import { describe, it, before, after } from 'mocha'
 import { describe, it, before, after } from 'mocha'
 import { expect } from 'chai'
 import { expect } from 'chai'
-import { By, Condition } from 'selenium-webdriver'
+import { By } from 'selenium-webdriver'
 import {
 import {
-  takeScreenshot,
   takeScreenshotOnFailure,
   takeScreenshotOnFailure,
   findExecutionDialog,
   findExecutionDialog,
   requireExecutionDialogStatus,
   requireExecutionDialogStatus,

+ 4 - 5
integration-tests/tests/stdoutMostRecentExecution/stdoutMostRecentExecution.mjs

@@ -3,7 +3,6 @@ import { expect } from 'chai'
 import { By, Condition } from 'selenium-webdriver'
 import { By, Condition } from 'selenium-webdriver'
 import {
 import {
   getRootAndWait,
   getRootAndWait,
-  getActionButtons,
   takeScreenshotOnFailure,
   takeScreenshotOnFailure,
 } from '../../lib/elements.js'
 } from '../../lib/elements.js'
 
 
@@ -116,13 +115,13 @@ describe('config: stdout-most-recent-execution', function () {
           // Output should change from initial state and contain actual output
           // Output should change from initial state and contain actual output
           // (not "Waiting...", "No execution found", or the same as initialText)
           // (not "Waiting...", "No execution found", or the same as initialText)
           const hasChanged = newText !== initialText
           const hasChanged = newText !== initialText
-          const hasValidOutput = newText && 
-                                 !newText.includes('Waiting...') && 
-                                 !newText.includes('No execution found') && 
+          const hasValidOutput = newText &&
+                                 !newText.includes('Waiting...') &&
+                                 !newText.includes('No execution found') &&
                                  !newText.includes('Error:') &&
                                  !newText.includes('Error:') &&
                                  newText.trim().length > 0
                                  newText.trim().length > 0
           return hasChanged && hasValidOutput
           return hasChanged && hasValidOutput
-        } catch (e) {
+        } catch {
           return false
           return false
         }
         }
       }),
       }),