diff --git a/scm-ui/e2e-tests/cypress/integration/anonymousMode_disabled.spec.js b/scm-ui/e2e-tests/cypress/integration/anonymousMode_disabled.spec.js new file mode 100644 index 0000000000..0380681777 --- /dev/null +++ b/scm-ui/e2e-tests/cypress/integration/anonymousMode_disabled.spec.js @@ -0,0 +1,44 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +describe("With Anonymous mode disabled", () => { + before("Disable anonymous access", () => { + cy.login("scmadmin", "scmadmin"); + cy.setAnonymousMode("OFF"); + cy.byTestId("primary-navigation-logout").click(); + }); + + it("Should show login page without primary navigation", () => { + cy.byTestId("login-button"); + cy.containsNotByTestId("div", "primary-navigation-login"); + cy.containsNotByTestId("div", "primary-navigation-repositories"); + }); + it("Should redirect after login", () => { + cy.login("scmadmin", "scmadmin"); + + cy.visit("/me"); + cy.byTestId("footer-user-profile"); + cy.byTestId("primary-navigation-logout").click(); + }); +}); diff --git a/scm-ui/e2e-tests/cypress/integration/anonymousAccess.spec.js b/scm-ui/e2e-tests/cypress/integration/anonymousMode_full.spec.js similarity index 62% rename from scm-ui/e2e-tests/cypress/integration/anonymousAccess.spec.js rename to scm-ui/e2e-tests/cypress/integration/anonymousMode_full.spec.js index 608e8bda27..d9652cdcf7 100644 --- a/scm-ui/e2e-tests/cypress/integration/anonymousAccess.spec.js +++ b/scm-ui/e2e-tests/cypress/integration/anonymousMode_full.spec.js @@ -22,52 +22,10 @@ * SOFTWARE. */ -describe("With Anonymous mode disabled", () => { - before("Disable anonymous access", () => { - cy.login("scmadmin", "scmadmin"); - setAnonymousMode("OFF"); - cy.byTestId("primary-navigation-logout").click(); - }); - - it("Should show login page without primary navigation", () => { - cy.byTestId("login-button"); - cy.containsNotByTestId("div", "primary-navigation-login"); - cy.containsNotByTestId("div", "primary-navigation-repositories"); - }); - it("Should redirect after login", () => { - cy.login("scmadmin", "scmadmin"); - - cy.visit("/me"); - cy.byTestId("footer-user-profile"); - cy.byTestId("primary-navigation-logout").click(); - }); -}); - -describe("With Anonymous mode protocol only enabled", () => { - before("Set anonymous mode to protocol only", () => { - cy.login("scmadmin", "scmadmin"); - setAnonymousMode("PROTOCOL_ONLY"); - cy.byTestId("primary-navigation-logout").click(); - }); - - it("Should show login page without primary navigation", () => { - cy.visit("/repos/"); - cy.byTestId("login-button"); - cy.containsNotByTestId("div", "primary-navigation-login"); - cy.containsNotByTestId("div", "primary-navigation-repositories"); - }); - - after("Disable anonymous access", () => { - cy.login("scmadmin", "scmadmin"); - setAnonymousMode("OFF"); - cy.byTestId("primary-navigation-logout").click(); - }); -}); - describe("With Anonymous mode fully enabled", () => { before("Set anonymous mode to full", () => { cy.login("scmadmin", "scmadmin"); - setAnonymousMode("FULL"); + cy.setAnonymousMode("FULL"); // Give anonymous user permissions cy.byTestId("primary-navigation-users").click(); @@ -83,7 +41,7 @@ describe("With Anonymous mode fully enabled", () => { it("Should show repositories overview with Login button in primary navigation", () => { cy.visit("/repos/"); cy.byTestId("repository-overview-filter"); - cy.byTestId("SCM-Anonymous"); + cy.byTestId("scm-anonymous"); cy.byTestId("primary-navigation-login"); }); it("Should show login page on url", () => { @@ -100,7 +58,7 @@ describe("With Anonymous mode fully enabled", () => { cy.login("scmadmin", "scmadmin"); cy.visit("/login"); - cy.byTestId("SCM-Administrator"); + cy.byTestId("scm-administrator"); cy.byTestId("primary-navigation-logout").click(); }); it("Should logout and direct to login page", () => { @@ -108,30 +66,21 @@ describe("With Anonymous mode fully enabled", () => { cy.visit("/repos/"); cy.byTestId("repository-overview-filter"); - cy.byTestId("SCM-Administrator"); + cy.byTestId("scm-administrator"); cy.byTestId("primary-navigation-logout").click(); cy.byTestId("login-button"); }); it("Anonymous user should not be able to change password", () => { cy.visit("/repos/"); cy.byTestId("footer-user-profile").click(); - cy.byTestId("SCM-Anonymous"); + cy.byTestId("scm-anonymous"); cy.containsNotByTestId("ul", "user-settings-link"); cy.get("section").not("Change password"); }); after("Disable anonymous access", () => { cy.login("scmadmin", "scmadmin"); - setAnonymousMode("OFF"); + cy.setAnonymousMode("OFF"); cy.byTestId("primary-navigation-logout").click(); }); }); - -const setAnonymousMode = anonymousMode => { - cy.byTestId("primary-navigation-admin").click(); - cy.byTestId("admin-settings-link").click(); - cy.byTestId("anonymous-mode-select") - .select(anonymousMode) - .should("have.value", anonymousMode); - cy.byTestId("submit-button").click(); -}; diff --git a/scm-ui/e2e-tests/cypress/integration/anonymousMode_protocolOnly.spec.js b/scm-ui/e2e-tests/cypress/integration/anonymousMode_protocolOnly.spec.js new file mode 100644 index 0000000000..fd223f3ae4 --- /dev/null +++ b/scm-ui/e2e-tests/cypress/integration/anonymousMode_protocolOnly.spec.js @@ -0,0 +1,44 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +describe("With Anonymous mode protocol only enabled", () => { + before("Set anonymous mode to protocol only", () => { + cy.login("scmadmin", "scmadmin"); + cy.setAnonymousMode("PROTOCOL_ONLY"); + cy.byTestId("primary-navigation-logout").click(); + }); + + it("Should show login page without primary navigation", () => { + cy.visit("/repos/"); + cy.byTestId("login-button"); + cy.containsNotByTestId("div", "primary-navigation-login"); + cy.containsNotByTestId("div", "primary-navigation-repositories"); + }); + + after("Disable anonymous access", () => { + cy.login("scmadmin", "scmadmin"); + cy.setAnonymousMode("OFF"); + cy.byTestId("primary-navigation-logout").click(); + }); +}); diff --git a/scm-ui/e2e-tests/cypress/support/commands.js b/scm-ui/e2e-tests/cypress/support/commands.js index e0a4923e7d..2e7bb6ec65 100644 --- a/scm-ui/e2e-tests/cypress/support/commands.js +++ b/scm-ui/e2e-tests/cypress/support/commands.js @@ -47,15 +47,23 @@ // -- This will overwrite an existing command -- // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) - const login = (username, password) => { - cy.visit( "/login"); + cy.visit("/login"); cy.byTestId("username-input").type(username); cy.byTestId("password-input").type(password); cy.byTestId("login-button").click(); }; -Cypress.Commands.add("login", login); -Cypress.Commands.add("byTestId", (testId) => cy.get("[data-testid=" + testId + "]")); -Cypress.Commands.add("containsNotByTestId", (container, testId) => cy.get(container).not("[data-testid=" + testId + "]")); +const setAnonymousMode = anonymousMode => { + cy.byTestId("primary-navigation-admin").click(); + cy.byTestId("admin-settings-link").click(); + cy.byTestId("anonymous-mode-select") + .select(anonymousMode) + .should("have.value", anonymousMode); + cy.byTestId("submit-button").click(); +}; +Cypress.Commands.add("login", login); +Cypress.Commands.add("setAnonymousMode", setAnonymousMode); +Cypress.Commands.add("byTestId", testId => cy.get(`[data-testid=${testId}]`)); +Cypress.Commands.add("containsNotByTestId", (container, testId) => cy.get(container).not(`[data-testid=${testId}]`)); diff --git a/scm-ui/e2e-tests/package.json b/scm-ui/e2e-tests/package.json index 00870e8b76..fd7a7c2c23 100644 --- a/scm-ui/e2e-tests/package.json +++ b/scm-ui/e2e-tests/package.json @@ -7,9 +7,19 @@ "license": "MIT", "private": false, "devDependencies": { - "cypress": "^4.12.0" + "cypress": "^4.12.0", + "eslint-plugin-cypress": "^2.11.1" }, "prettier": "@scm-manager/prettier-config", + "eslintConfig": { + "extends": "@scm-manager/eslint-config", + "plugins": [ + "cypress" + ], + "env": { + "cypress/globals": true + } + }, "publishConfig": { "access": "public" } diff --git a/scm-ui/ui-components/src/devBuild.test.ts b/scm-ui/ui-components/src/devBuild.test.ts index 6ca0373733..8df47ec6ee 100644 --- a/scm-ui/ui-components/src/devBuild.test.ts +++ b/scm-ui/ui-components/src/devBuild.test.ts @@ -73,7 +73,7 @@ describe("devbuild tests", () => { expect(attributes).toBeUndefined(); }); - it("should normalize testid testid", () => { + it("should remove spaces from test id", () => { const attributes = createAttributesForTesting("heart of gold"); if (attributes) { expect(attributes["data-testid"]).toBe("heart-of-gold"); @@ -81,5 +81,14 @@ describe("devbuild tests", () => { throw new Error("attributes should be defined"); } }); + + it("should lower case test id", () => { + const attributes = createAttributesForTesting("HeartOfGold"); + if (attributes) { + expect(attributes["data-testid"]).toBe("heartofgold"); + } else { + throw new Error("attributes should be defined"); + } + }); }); }); diff --git a/scm-ui/ui-components/src/devBuild.ts b/scm-ui/ui-components/src/devBuild.ts index b8d686b749..abf1a18dc7 100644 --- a/scm-ui/ui-components/src/devBuild.ts +++ b/scm-ui/ui-components/src/devBuild.ts @@ -34,7 +34,7 @@ export const createAttributesForTesting = (testId?: string) => { }; const normalizeTestId = (testId: string) => { - let id = testId; + let id = testId.toLowerCase(); while (id.includes(" ")) { id = id.replace(" ", "-"); } diff --git a/scm-ui/ui-webapp/src/permissions/components/PermissionCheckbox.tsx b/scm-ui/ui-webapp/src/permissions/components/PermissionCheckbox.tsx index 79e53014f3..7939f73b0e 100644 --- a/scm-ui/ui-webapp/src/permissions/components/PermissionCheckbox.tsx +++ b/scm-ui/ui-webapp/src/permissions/components/PermissionCheckbox.tsx @@ -45,9 +45,6 @@ class PermissionCheckbox extends React.Component { ? t("verbs.repository." + name + ".description") : this.translateOrDefault("permissions." + key + ".description", t("permissions.unknown")); - // @ts-ignore we have to use the label here because cypress gets confused with asterix and dots - const testId = label.replaceAll(" ", "-").toLowerCase(); - return ( { checked={checked} onChange={onChange} disabled={disabled} - testId={testId} + testId={label} /> ); } diff --git a/yarn.lock b/yarn.lock index dd8391c3eb..a6f9f597d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4239,11 +4239,6 @@ babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.2" -babel-core@7.0.0-bridge.0: - version "7.0.0-bridge.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" - integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== - babel-eslint@^10.0.3: version "10.1.0" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" @@ -7256,6 +7251,13 @@ eslint-module-utils@^2.4.1: debug "^2.6.9" pkg-dir "^2.0.0" +eslint-plugin-cypress@^2.11.1: + version "2.11.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-cypress/-/eslint-plugin-cypress-2.11.1.tgz#a945e2774b88211e2c706a059d431e262b5c2862" + integrity sha512-MxMYoReSO5+IZMGgpBZHHSx64zYPSPTpXDwsgW7ChlJTF/sA+obqRbHplxD6sBStE+g4Mi0LCLkG4t9liu//mQ== + dependencies: + globals "^11.12.0" + eslint-plugin-flowtype@^4.3.0: version "4.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-4.7.0.tgz#903a6ea3eb5cbf4c7ba7fa73cc43fc39ab7e4a70" @@ -7736,7 +7738,7 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fault@^1.0.0: +fault@^1.0.0, fault@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== @@ -8304,7 +8306,7 @@ gitconfiglocal@^1.0.0: dependencies: ini "^1.3.2" -gitdiff-parser@^0.1.2, "gitdiff-parser@https://github.com/scm-manager/gitdiff-parser#617747460280bf4522bb84d217a9064ac8eb6d3d": +gitdiff-parser@^0.1.2: version "0.1.2" resolved "https://github.com/scm-manager/gitdiff-parser#617747460280bf4522bb84d217a9064ac8eb6d3d" @@ -8411,7 +8413,7 @@ global@^4.3.2, global@^4.4.0: min-document "^2.19.0" process "^0.11.10" -globals@^11.1.0: +globals@^11.1.0, globals@^11.12.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== @@ -11292,7 +11294,7 @@ lower-case@^2.0.1: dependencies: tslib "^1.10.0" -lowlight@1.13.1, lowlight@^1.13.0, lowlight@~1.11.0: +lowlight@^1.13.0: version "1.13.1" resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.13.1.tgz#c4f0e03906ebd23fedf2d258f6ab2f6324cf90eb" integrity sha512-kQ71/T6RksEVz9AlPq07/2m+SU/1kGvt9k39UtvHX760u4SaWakaYH7hYgH5n6sTsCWk4MVYzUzLU59aN5CSmQ== @@ -11300,6 +11302,14 @@ lowlight@1.13.1, lowlight@^1.13.0, lowlight@~1.11.0: fault "^1.0.0" highlight.js "~9.16.0" +lowlight@~1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.11.0.tgz#1304d83005126d4e8b1dc0f07981e9b689ec2efc" + integrity sha512-xrGGN6XLL7MbTMdPD6NfWPwY43SNkjf/d0mecSx/CW36fUZTjRHEq0/Cdug3TWKtRXLWi7iMl1eP0olYxj/a4A== + dependencies: + fault "^1.0.2" + highlight.js "~9.13.0" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"