diff --git a/v3/.eslintrc.build.cjs b/v3/.eslintrc.build.cjs index 8f947be8c7..440c9c19ea 100644 --- a/v3/.eslintrc.build.cjs +++ b/v3/.eslintrc.build.cjs @@ -10,7 +10,13 @@ module.exports = { { // rules specific to Jest tests files: ["src/**/*.test.*", "src/test/**"], rules: { - "jest/no-focused-tests": "warn" + "jest/no-focused-tests": "error" + } + }, + { // rules specific to Cypress tests + files: ["cypress/**"], + rules: { + "mocha/no-exclusive-tests": "error" } } ] diff --git a/v3/.eslintrc.cjs b/v3/.eslintrc.cjs index 59eaace0c1..b07e618d98 100644 --- a/v3/.eslintrc.cjs +++ b/v3/.eslintrc.cjs @@ -141,7 +141,7 @@ module.exports = { "@typescript-eslint/no-var-requires": "off", "jest/no-disabled-tests": "off", "jest/no-done-callback": "off", - "jest/no-focused-tests": "off" // enabled in .eslintrc.build.js + "jest/no-focused-tests": "warn" // error in .eslintrc.build.js } }, { // rules specific to Cypress tests @@ -150,14 +150,20 @@ module.exports = { node: true, "cypress/globals": true }, - plugins: ["cypress"], - extends: ["plugin:cypress/recommended"], + plugins: ["cypress", "mocha"], + extends: ["plugin:cypress/recommended", "plugin:mocha/recommended"], rules: { "@typescript-eslint/no-require-imports": "off", "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-var-requires": "off", "cypress/no-unnecessary-waiting": "off", - "cypress/unsafe-to-chain-command": "off" // FIXME: eight errors reported + "cypress/unsafe-to-chain-command": "off", // FIXME: multiple errors reported + "mocha/consistent-spacing-between-blocks": "off", + "mocha/max-top-level-suites": "off", + "mocha/no-exclusive-tests": "warn", // error in .eslintrc.build.js + "mocha/no-mocha-arrows": "off", + "mocha/no-setup-in-describe": "off", + "mocha/no-skipped-tests": "off", } }, { // Lint configs in the base v3 directory diff --git a/v3/cypress/e2e/case-card.spec.ts b/v3/cypress/e2e/case-card.spec.ts index 12660ddbe4..22921fc44e 100644 --- a/v3/cypress/e2e/case-card.spec.ts +++ b/v3/cypress/e2e/case-card.spec.ts @@ -1,13 +1,13 @@ -beforeEach(() => { - // cy.scrollTo() doesn't work as expected with `scroll-behavior: smooth` - const queryParams = "?sample=mammals&scrollBehavior=auto" - const url = `${Cypress.config("index")}${queryParams}` - cy.visit(url) - cy.wait(2000) -}) - context("case card", () => { + beforeEach(() => { + // cy.scrollTo() doesn't work as expected with `scroll-behavior: smooth` + const queryParams = "?sample=mammals&scrollBehavior=auto" + const url = `${Cypress.config("index")}${queryParams}` + cy.visit(url) + cy.wait(2000) + }) + describe("case card", () => { it("can switch from case table to case card view and back", () => { const tableHeaderLeftSelector = ".codap-component.codap-case-table .component-title-bar .header-left" diff --git a/v3/cypress/e2e/table.spec.ts b/v3/cypress/e2e/table.spec.ts index 910dd6a7cf..38361acb06 100644 --- a/v3/cypress/e2e/table.spec.ts +++ b/v3/cypress/e2e/table.spec.ts @@ -3,30 +3,30 @@ import { ComponentElements as c } from "../support/elements/component-elements" import { ToolbarElements as toolbar } from "../support/elements/toolbar-elements" import { FormulaHelper as fh } from "../support/helpers/formula-helper" -const numOfAttributes = 10 -const firstRowIndex = 2 -let lastRowIndex = -1 -let middleRowIndex = -1 -let numOfCases = "0" -const collectionName = "Mammals" -const renamedCollectionName = "Animals" -const newCollectionName = "New Dataset" - -beforeEach(() => { - // cy.scrollTo() doesn't work as expected with `scroll-behavior: smooth` - const queryParams = "?sample=mammals&scrollBehavior=auto" - const url = `${Cypress.config("index")}${queryParams}` - cy.visit(url) - cy.wait(1000) - table.getNumOfAttributes().should("equal", numOfAttributes.toString()) - table.getNumOfRows().then($cases => { - numOfCases = $cases ?? "0" - lastRowIndex = Number($cases) - 1 - middleRowIndex = Math.min(5, Math.floor(lastRowIndex / 2)) +context("case table ui", () => { + const numOfAttributes = 10 + const firstRowIndex = 2 + let lastRowIndex = -1 + let middleRowIndex = -1 + let numOfCases = "0" + const collectionName = "Mammals" + const renamedCollectionName = "Animals" + const newCollectionName = "New Dataset" + + beforeEach(() => { + // cy.scrollTo() doesn't work as expected with `scroll-behavior: smooth` + const queryParams = "?sample=mammals&scrollBehavior=auto" + const url = `${Cypress.config("index")}${queryParams}` + cy.visit(url) + cy.wait(1000) + table.getNumOfAttributes().should("equal", numOfAttributes.toString()) + table.getNumOfRows().then($cases => { + numOfCases = $cases ?? "0" + lastRowIndex = Number($cases) - 1 + middleRowIndex = Math.min(5, Math.floor(lastRowIndex / 2)) + }) }) -}) -context("case table ui", () => { describe("table view", () => { it("populates title bar from sample data", () => { c.getComponentTitle("table").should("contain", collectionName) diff --git a/v3/package-lock.json b/v3/package-lock.json index 89bd3fc5b0..d6551d6625 100644 --- a/v3/package-lock.json +++ b/v3/package-lock.json @@ -92,6 +92,7 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-json": "^3.1.0", + "eslint-plugin-mocha": "^10.5.0", "eslint-plugin-react": "^7.34.3", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-testing-library": "^6.2.2", @@ -12497,6 +12498,50 @@ "node": ">=12.0" } }, + "node_modules/eslint-plugin-mocha": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.5.0.tgz", + "integrity": "sha512-F2ALmQVPT1GoP27O1JTZGrV9Pqg8k79OeIuvw63UxMtQKREZtmkK1NFgkZQ2TW7L2JSSFKHFPTtHu5z8R9QNRw==", + "dev": true, + "dependencies": { + "eslint-utils": "^3.0.0", + "globals": "^13.24.0", + "rambda": "^7.4.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-mocha/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-mocha/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-plugin-react": { "version": "7.34.3", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", @@ -12608,6 +12653,33 @@ "node": ">=4.0" } }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -20823,6 +20895,12 @@ } ] }, + "node_modules/rambda": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/rambda/-/rambda-7.5.0.tgz", + "integrity": "sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==", + "dev": true + }, "node_modules/random": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/random/-/random-4.1.0.tgz", @@ -34374,6 +34452,34 @@ "vscode-json-languageservice": "^4.1.6" } }, + "eslint-plugin-mocha": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.5.0.tgz", + "integrity": "sha512-F2ALmQVPT1GoP27O1JTZGrV9Pqg8k79OeIuvw63UxMtQKREZtmkK1NFgkZQ2TW7L2JSSFKHFPTtHu5z8R9QNRw==", + "dev": true, + "requires": { + "eslint-utils": "^3.0.0", + "globals": "^13.24.0", + "rambda": "^7.4.0" + }, + "dependencies": { + "globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, "eslint-plugin-react": { "version": "7.34.3", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", @@ -34456,6 +34562,23 @@ } } }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, "eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", @@ -40398,6 +40521,12 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "rambda": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/rambda/-/rambda-7.5.0.tgz", + "integrity": "sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==", + "dev": true + }, "random": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/random/-/random-4.1.0.tgz", diff --git a/v3/package.json b/v3/package.json index bc1781aa93..3d096f2cde 100644 --- a/v3/package.json +++ b/v3/package.json @@ -141,6 +141,7 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-json": "^3.1.0", + "eslint-plugin-mocha": "^10.5.0", "eslint-plugin-react": "^7.34.3", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-testing-library": "^6.2.2",