diff --git a/test/cypress/config/ci.mjs b/test/cypress/config/ci.mjs index 2597c194c..ea203a89e 100644 --- a/test/cypress/config/ci.mjs +++ b/test/cypress/config/ci.mjs @@ -2,6 +2,7 @@ import { defineConfig } from 'cypress'; import pluginSetup from '../plugins/index.mjs'; export default defineConfig({ + allowCypressEnv: false, requestTimeout: 30000, defaultCommandTimeout: 20000, reporter: "cypress-multi-reporters", diff --git a/test/cypress/config/dev.mjs b/test/cypress/config/dev.mjs index f32d973c8..636c3095c 100644 --- a/test/cypress/config/dev.mjs +++ b/test/cypress/config/dev.mjs @@ -2,6 +2,7 @@ import { defineConfig } from 'cypress'; import pluginSetup from '../plugins/index.mjs'; export default defineConfig({ + allowCypressEnv: false, requestTimeout: 30000, defaultCommandTimeout: 20000, reporter: "cypress-multi-reporters", diff --git a/test/cypress/e2e/api/Ldap.cy.js b/test/cypress/e2e/api/Ldap.cy.js deleted file mode 100644 index e1a999760..000000000 --- a/test/cypress/e2e/api/Ldap.cy.js +++ /dev/null @@ -1,65 +0,0 @@ -/// - -describe('LDAP with Authentik', () => { - let _token; - if (cy.env('skipStackCheck') === 'true' || cy.env('stack') === 'postgres') { - - before(() => { - cy.resetUsers(); - cy.getToken().then((tok) => { - _token = tok; - - // cy.task('backendApiPut', { - // token: token, - // path: '/api/settings/ldap-auth', - // data: { - // value: { - // host: 'authentik-ldap:3389', - // base_dn: 'ou=users,DC=ldap,DC=goauthentik,DC=io', - // user_dn: 'cn={{USERNAME}},ou=users,DC=ldap,DC=goauthentik,DC=io', - // email_property: 'mail', - // name_property: 'sn', - // self_filter: '(&(cn={{USERNAME}})(ak-active=TRUE))', - // auto_create_user: true - // } - // } - // }).then((data) => { - // cy.validateSwaggerSchema('put', 200, '/settings/{name}', data); - // expect(data.result).to.have.property('id'); - // expect(data.result.id).to.be.greaterThan(0); - // }); - - // cy.task('backendApiPut', { - // token: token, - // path: '/api/settings/auth-methods', - // data: { - // value: [ - // 'local', - // 'ldap' - // ] - // } - // }).then((data) => { - // cy.validateSwaggerSchema('put', 200, '/settings/{name}', data); - // expect(data.result).to.have.property('id'); - // expect(data.result.id).to.be.greaterThan(0); - // }); - }); - }); - - it.skip('Should log in with LDAP', () => { - // cy.task('backendApiPost', { - // token: token, - // path: '/api/auth', - // data: { - // // Authentik LDAP creds: - // type: 'ldap', - // identity: 'cypress', - // secret: 'fqXBfUYqHvYqiwBHWW7f' - // } - // }).then((data) => { - // cy.validateSwaggerSchema('post', 200, '/auth', data); - // expect(data.result).to.have.property('token'); - // }); - }); - } -}); diff --git a/test/cypress/e2e/api/OAuth.cy.js b/test/cypress/e2e/api/OAuth.cy.js deleted file mode 100644 index 55e78f52d..000000000 --- a/test/cypress/e2e/api/OAuth.cy.js +++ /dev/null @@ -1,97 +0,0 @@ -/// - -describe('OAuth with Authentik', () => { - let _token; - if (cy.env('skipStackCheck') === 'true' || cy.env('stack') === 'postgres') { - - before(() => { - cy.getToken().then((tok) => { - _token = tok; - - // cy.task('backendApiPut', { - // token: token, - // path: '/api/settings/oauth-auth', - // data: { - // value: { - // client_id: '7iO2AvuUp9JxiSVkCcjiIbQn4mHmUMBj7yU8EjqU', - // client_secret: 'VUMZzaGTrmXJ8PLksyqzyZ6lrtz04VvejFhPMBP9hGZNCMrn2LLBanySs4ta7XGrDr05xexPyZT1XThaf4ubg00WqvHRVvlu4Naa1aMootNmSRx3VAk6RSslUJmGyHzq', - // authorization_url: 'http://authentik:9000/application/o/authorize/', - // resource_url: 'http://authentik:9000/application/o/userinfo/', - // token_url: 'http://authentik:9000/application/o/token/', - // logout_url: 'http://authentik:9000/application/o/npm/end-session/', - // identifier: 'preferred_username', - // scopes: [], - // auto_create_user: true - // } - // } - // }).then((data) => { - // cy.validateSwaggerSchema('put', 200, '/settings/{name}', data); - // expect(data.result).to.have.property('id'); - // expect(data.result.id).to.be.greaterThan(0); - // }); - - // cy.task('backendApiPut', { - // token: token, - // path: '/api/settings/auth-methods', - // data: { - // value: [ - // 'local', - // 'oauth' - // ] - // } - // }).then((data) => { - // cy.validateSwaggerSchema('put', 200, '/settings/{name}', data); - // expect(data.result).to.have.property('id'); - // expect(data.result.id).to.be.greaterThan(0); - // }); - }); - }); - - it.skip('Should log in with OAuth', () => { - // cy.task('backendApiGet', { - // path: '/oauth/login?redirect_base=' + encodeURI(Cypress.config('baseUrl')), - // }).then((data) => { - // expect(data).to.have.property('result'); - - // cy.origin('http://authentik:9000', {args: data.result}, (url) => { - // cy.visit(url); - // cy.get('ak-flow-executor') - // .shadow() - // .find('ak-stage-identification') - // .shadow() - // .find('input[name="uidField"]', { visible: true }) - // .type('cypress'); - - // cy.get('ak-flow-executor') - // .shadow() - // .find('ak-stage-identification') - // .shadow() - // .find('button[type="submit"]', { visible: true }) - // .click(); - - // cy.get('ak-flow-executor') - // .shadow() - // .find('ak-stage-password') - // .shadow() - // .find('input[name="password"]', { visible: true }) - // .type('fqXBfUYqHvYqiwBHWW7f'); - - // cy.get('ak-flow-executor') - // .shadow() - // .find('ak-stage-password') - // .shadow() - // .find('button[type="submit"]', { visible: true }) - // .click(); - // }) - - // // we should be logged in - // cy.get('#root p.chakra-text') - // .first() - // .should('have.text', 'Nginx Proxy Manager'); - - // // logout: - // cy.clearLocalStorage(); - // }); - }); - } -}); diff --git a/test/cypress/e2e/api/Streams.cy.js b/test/cypress/e2e/api/Streams.cy.js index 10809f894..b2c97b440 100644 --- a/test/cypress/e2e/api/Streams.cy.js +++ b/test/cypress/e2e/api/Streams.cy.js @@ -23,11 +23,13 @@ describe('Streams', () => { }); // Create a custom cert pair - cy.exec('mkcert -cert-file=/test/cypress/fixtures/website1.pem -key-file=/test/cypress/fixtures/website1.key.pem website1.example.com').then((result) => { - expect(result.exitCode).to.eq(0); - // Install CA - cy.exec('mkcert -install').then((result) => { + cy.task('getFixturesFolder').then((fixturesFolder) => { + cy.exec(`mkcert -cert-file=${fixturesFolder}/website1.pem -key-file=${fixturesFolder}/website1.key.pem website1.example.com`).then((result) => { expect(result.exitCode).to.eq(0); + // Install CA + cy.exec('mkcert -install').then((result) => { + expect(result.exitCode).to.eq(0); + }); }); }); diff --git a/test/cypress/plugins/index.mjs b/test/cypress/plugins/index.mjs index 1058d6338..dc09527dc 100644 --- a/test/cypress/plugins/index.mjs +++ b/test/cypress/plugins/index.mjs @@ -22,6 +22,11 @@ export default (on, config) => { return null; }, }); + on('task', { + getFixturesFolder() { + return config.fixturesFolder + }, + }); return config; }; diff --git a/test/cypress/support/commands.mjs b/test/cypress/support/commands.mjs index 3f12d0ef7..12db1994e 100644 --- a/test/cypress/support/commands.mjs +++ b/test/cypress/support/commands.mjs @@ -10,7 +10,6 @@ // import 'cypress-wait-until'; -import { createCA, createCert } from 'mkcert'; Cypress.Commands.add('randomString', (length) => { let result = ''; @@ -49,14 +48,16 @@ Cypress.Commands.add("validateSwaggerFile", (url, savePath) => { * @param {*} data The API response data to check against the swagger schema */ Cypress.Commands.add('validateSwaggerSchema', (method, code, path, data) => { - cy.task('validateSwaggerSchema', { - file: cy.env('swaggerBase'), - endpoint: path, - method: method, - statusCode: code, - responseSchema: data, - verbose: true - }).should('equal', null); + cy.env(['swaggerBase']).then(({ swaggerBase }) => { + cy.task('validateSwaggerSchema', { + file: swaggerBase, + endpoint: path, + method: method, + statusCode: code, + responseSchema: data, + verbose: true + }).should('equal', null); + }); }); Cypress.Commands.add('createInitialUser', (defaultUser) => { @@ -156,21 +157,15 @@ Cypress.Commands.add('waitForCertificateStatus', (token, certID, expected, timeo // Creates CA files for testing, if they already exist they will be deleted // and recreated with the same content. This is to ensure that the files exist // for testing and are in a known state. -Cypress.Commands.add('createCustomCerts', async () => { - const ca = await createCA({ - organization: "NPM CA", - countryCode: "AU", - state: "QLD", - locality: "Brisbane", - validity: 365 +Cypress.Commands.add('createCustomCerts', () => { + cy.task('getFixturesFolder').then((fixturesFolder) => { + cy.exec(`mkcert -cert-file=${fixturesFolder}/test.example.com.pem -key-file=${fixturesFolder}/test.example.com-key.pem test.example.com`) + .then((result) => { + expect(result.exitCode).to.eq(0); + // Install CA + cy.exec('mkcert -install').then((result) => { + expect(result.exitCode).to.eq(0); + }); + }); }); - - const cert = await createCert({ - ca: { key: ca.key, cert: ca.cert }, - domains: ["test.example.com"], - validity: 365 - }); - - cy.writeFile(`${config.fixturesFolder}/test.example.com.pem`, cert.cert); - cy.writeFile(`${config.fixturesFolder}/test.example.com-key.pem`, cert.key); }); diff --git a/test/cypress/support/task.mjs b/test/cypress/support/task.mjs new file mode 100644 index 000000000..edc5015c6 --- /dev/null +++ b/test/cypress/support/task.mjs @@ -0,0 +1,100 @@ +import fs from "node:fs"; +import FormData from "form-data"; +import Client from "./client.mjs"; +import logger from "./logger.mjs"; + +export default (config) => { + logger("Client Ready using", config.baseUrl); + + return { + /** + * @param {object} options + * @param {string} options.path API path + * @param {string} [options.token] JWT + * @param {bool} [options.returnOnError] If true, will return instead of throwing errors + * @returns {string} + */ + backendApiGet: (options) => { + const api = new Client(config); + api.setToken(options.token); + return api.request("get", options.path, options.returnOnError || false); + }, + + /** + * @param {object} options + * @param {string} options.token JWT + * @param {string} options.path API path + * @param {object} options.data + * @param {bool} [options.returnOnError] If true, will return instead of throwing errors + * @returns {string} + */ + backendApiPost: (options) => { + const api = new Client(config); + api.setToken(options.token); + return api.request( + "post", + options.path, + options.returnOnError || false, + options.data, + ); + }, + + /** + * @param {object} options + * @param {string} options.token JWT + * @param {string} options.path API path + * @param {object} options.files + * @param {bool} [options.returnOnError] If true, will return instead of throwing errors + * @returns {string} + */ + backendApiPostFiles: (options) => { + const api = new Client(config); + api.setToken(options.token); + + const form = new FormData(); + for (const [key, value] of Object.entries(options.files)) { + form.append( + key, + fs.createReadStream(`${config.fixturesFolder}/${value}`), + ); + } + return api.postForm(options.path, form, options.returnOnError || false); + }, + + /** + * @param {object} options + * @param {string} options.token JWT + * @param {string} options.path API path + * @param {object} options.data + * @param {bool} [options.returnOnError] If true, will return instead of throwing errors + * @returns {string} + */ + backendApiPut: (options) => { + const api = new Client(config); + api.setToken(options.token); + return api.request( + "put", + options.path, + options.returnOnError || false, + options.data, + ); + }, + + /** + * @param {object} options + * @param {string} options.token JWT + * @param {string} options.path API path + * @param {bool} [options.returnOnError] If true, will return instead of throwing errors + * @returns {string} + */ + backendApiDelete: (options) => { + const api = new Client(config); + api.setToken(options.token); + return api.request( + "delete", + options.path, + options.returnOnError || false, + ); + }, + }; +}; diff --git a/test/package.json b/test/package.json index b243cc410..555bb6c29 100644 --- a/test/package.json +++ b/test/package.json @@ -17,7 +17,6 @@ "eslint-plugin-cypress": "^6.4.1", "form-data": "^4.0.5", "lodash": "^4.18.1", - "mkcert": "^3.2.0", "mocha": "^11.7.5", "mocha-junit-reporter": "^2.2.1" }, diff --git a/test/yarn.lock b/test/yarn.lock index 0d3f07143..57e4b4732 100644 --- a/test/yarn.lock +++ b/test/yarn.lock @@ -567,11 +567,6 @@ combined-stream@^1.0.8, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^11.0.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" - integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== - commander@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" @@ -1566,14 +1561,6 @@ minizlib@^3.1.0: dependencies: minipass "^7.1.2" -mkcert@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/mkcert/-/mkcert-3.2.0.tgz#6c4d58bbb31dbf76efd24f197d454702b14020f4" - integrity sha512-026Eivq9RoOjOuLJGzbhGwXUAjBxRX11Z7Jbm4/7lqT/Av+XNy9SPrJte6+UpEt7i+W3e/HZYxQqlQcqXZWSzg== - dependencies: - commander "^11.0.0" - node-forge "^1.3.1" - mkdirp@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" @@ -1641,11 +1628,6 @@ node-fetch@^3.3.2: fetch-blob "^3.1.4" formdata-polyfill "^4.0.10" -node-forge@^1.3.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.4.0.tgz#1c7b7d8bdc2d078739f58287d589d903a11b2fc2" - integrity sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ== - npm-run-path@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"