From 8313d6f8013055e80a9b2e42e1405d5688dd4b04 Mon Sep 17 00:00:00 2001 From: Ken Sternberg Date: Fri, 25 Aug 2023 15:30:09 -0700 Subject: [PATCH] web: completed test for single application, provided new programming language to make it easier to write tests. --- web/authentik-live-tests/lib/idiom.js | 36 ++++ web/authentik-live-tests/package-lock.json | 186 ++++++++++++++++-- web/authentik-live-tests/package.json | 1 + web/authentik-live-tests/tests/login.test.js | 98 +++++---- ...ion-wizard-authentication-method-choice.ts | 6 + 5 files changed, 256 insertions(+), 71 deletions(-) create mode 100644 web/authentik-live-tests/lib/idiom.js diff --git a/web/authentik-live-tests/lib/idiom.js b/web/authentik-live-tests/lib/idiom.js new file mode 100644 index 000000000..f69bfadc5 --- /dev/null +++ b/web/authentik-live-tests/lib/idiom.js @@ -0,0 +1,36 @@ +"use strict"; + +const CLICK_TIME_DELAY = 250; + +async function text(selector, value) { + const input = await $(selector); + return await input.setValue(value); +} + +async function button(selector) { + console.log("HEY:", selector); + const button = await $(selector); + return await button.click(); +} + +async function search(searchSelector, buttonSelector) { + const inputBind = await $(searchSelector); + await inputBind.click(); + const searchBlock = await $('>>>div[data-managed-by="ak-search-select"]'); + const target = searchBlock.$(buttonSelector); + return await target.click(); +} + +async function pause(selector) { + if (selector) { + return await $(selector).waitForDisplayed(); + } + return await browser.pause(CLICK_TIME_DELAY); +} + +exports.$AkSel = { + button, + pause, + search, + text, +}; diff --git a/web/authentik-live-tests/package-lock.json b/web/authentik-live-tests/package-lock.json index f9d3cb08c..e646334df 100644 --- a/web/authentik-live-tests/package-lock.json +++ b/web/authentik-live-tests/package-lock.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "@wdio/cli": "^8.15.6", + "@wdio/types": "^8.15.7", "prettier": "^3.0.2" }, "devDependencies": { @@ -1586,6 +1587,23 @@ "node": ">=12.0.0" } }, + "node_modules/@wdio/config/node_modules/@wdio/types": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", + "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "^18.0.0", + "got": "^11.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "^4.6.2" + } + }, "node_modules/@wdio/config/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -4628,22 +4646,21 @@ } }, "node_modules/@wdio/types": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", - "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", - "dev": true, - "peer": true, + "version": "8.15.7", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.15.7.tgz", + "integrity": "sha512-zxst2NBSMAUozcB1L/UVfdxfC9E6JPUCd1owZnS1xKo4XqXgRyzLSOTOc5TIegtrPmO9gFIdNzjnV34oehLNIQ==", "dependencies": { - "@types/node": "^18.0.0", - "got": "^11.8.1" + "@types/node": "^20.1.0" }, "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "^4.6.2" + "node": "^16.13 || >=18" } }, + "node_modules/@wdio/types/node_modules/@types/node": { + "version": "20.5.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.6.tgz", + "integrity": "sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==" + }, "node_modules/@wdio/utils": { "version": "7.20.3", "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.20.3.tgz", @@ -4659,6 +4676,23 @@ "node": ">=12.0.0" } }, + "node_modules/@wdio/utils/node_modules/@wdio/types": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", + "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "^18.0.0", + "got": "^11.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "^4.6.2" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -5698,6 +5732,23 @@ "devOptional": true, "peer": true }, + "node_modules/devtools/node_modules/@wdio/types": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", + "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "^18.0.0", + "got": "^11.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "^4.6.2" + } + }, "node_modules/diff": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", @@ -10982,6 +11033,23 @@ "node": ">=12.0.0" } }, + "node_modules/webdriver/node_modules/@wdio/types": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", + "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "^18.0.0", + "got": "^11.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "^4.6.2" + } + }, "node_modules/webdriverio": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-7.20.5.tgz", @@ -11021,6 +11089,23 @@ "node": ">=12.0.0" } }, + "node_modules/webdriverio/node_modules/@wdio/types": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", + "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "^18.0.0", + "got": "^11.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "^4.6.2" + } + }, "node_modules/webdriverio/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -12566,6 +12651,17 @@ "glob": "^8.0.3" }, "dependencies": { + "@wdio/types": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", + "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", + "dev": true, + "peer": true, + "requires": { + "@types/node": "^18.0.0", + "got": "^11.8.1" + } + }, "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -14751,14 +14847,18 @@ } }, "@wdio/types": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", - "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", - "dev": true, - "peer": true, + "version": "8.15.7", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.15.7.tgz", + "integrity": "sha512-zxst2NBSMAUozcB1L/UVfdxfC9E6JPUCd1owZnS1xKo4XqXgRyzLSOTOc5TIegtrPmO9gFIdNzjnV34oehLNIQ==", "requires": { - "@types/node": "^18.0.0", - "got": "^11.8.1" + "@types/node": "^20.1.0" + }, + "dependencies": { + "@types/node": { + "version": "20.5.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.6.tgz", + "integrity": "sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==" + } } }, "@wdio/utils": { @@ -14771,6 +14871,19 @@ "@wdio/logger": "7.19.0", "@wdio/types": "7.20.3", "p-iteration": "^1.1.8" + }, + "dependencies": { + "@wdio/types": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", + "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", + "dev": true, + "peer": true, + "requires": { + "@types/node": "^18.0.0", + "got": "^11.8.1" + } + } } }, "agent-base": { @@ -15530,6 +15643,19 @@ "query-selector-shadow-dom": "^1.0.0", "ua-parser-js": "^1.0.1", "uuid": "^8.0.0" + }, + "dependencies": { + "@wdio/types": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", + "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", + "dev": true, + "peer": true, + "requires": { + "@types/node": "^18.0.0", + "got": "^11.8.1" + } + } } }, "devtools-protocol": { @@ -19334,6 +19460,19 @@ "got": "^11.0.2", "ky": "^0.30.0", "lodash.merge": "^4.6.1" + }, + "dependencies": { + "@wdio/types": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", + "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", + "dev": true, + "peer": true, + "requires": { + "@types/node": "^18.0.0", + "got": "^11.8.1" + } + } } }, "webdriverio": { @@ -19372,6 +19511,17 @@ "webdriver": "7.20.4" }, "dependencies": { + "@wdio/types": { + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.20.3.tgz", + "integrity": "sha512-5q1urjM2Q1eYFZSxKO9Uhj86rt2NWS70c2rbbnKaB9oNNHUVtFFqSKNKAkJ84rNAfo/atWqWup7VSlg3BLrGNg==", + "dev": true, + "peer": true, + "requires": { + "@types/node": "^18.0.0", + "got": "^11.8.1" + } + }, "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", diff --git a/web/authentik-live-tests/package.json b/web/authentik-live-tests/package.json index 5078c4497..a78234af0 100644 --- a/web/authentik-live-tests/package.json +++ b/web/authentik-live-tests/package.json @@ -17,6 +17,7 @@ }, "dependencies": { "@wdio/cli": "^8.15.6", + "@wdio/types": "^8.15.7", "prettier": "^3.0.2" } } diff --git a/web/authentik-live-tests/tests/login.test.js b/web/authentik-live-tests/tests/login.test.js index eae2a38f6..334858574 100644 --- a/web/authentik-live-tests/tests/login.test.js +++ b/web/authentik-live-tests/tests/login.test.js @@ -1,67 +1,59 @@ -const { execSync } = require('child_process') -const { readdirSync } = require('fs') -const path = require('path') +const { execSync } = require("child_process"); +const { readdirSync } = require("fs"); +const path = require("path"); +const { $AkSel } = require("../lib/idiom"); const CLICK_TIME_DELAY = 250; -describe('Login', () => { +const login = [ + ['text', '>>>input[name="uidField"]', "ken@goauthentik.io"], + ['button', '>>>button[type="submit"]'], + ['pause'], + ['text', '>>>input[name="password"]', "eat10bugs"], + ['button', '>>>button[type="submit"]'], + ['pause', ">>>div.header h1"], +]; + + +const simpleApplication = [ + ['text', '>>>ak-form-element-horizontal input[name="name"]', "This Is My Application"], + ['button', ">>>ak-wizard-frame footer button.pf-m-primary"], + ['button', '>>>input[value="ldapprovider"]'], + ['button', ">>>ak-wizard-frame footer button.pf-m-primary"], + ['text', '>>>ak-form-element-horizontal input[name="name"]', "This Is My Provider"], + ['search', '>>>ak-tenanted-flow-search input[type="text"]', "button*=default-authentication-flow"], + ['text', '>>>ak-form-element-horizontal input[name="tlsServerName"]', "example.goauthentik.io"], + ['button', ">>>ak-wizard-frame footer button.pf-m-primary"] +]; + + +describe("Login", () => { it(`Should correctly log in to Authentik}`, async () => { - await browser.reloadSession() - await browser.url("http://localhost:9000") + await browser.reloadSession(); + await browser.url("http://localhost:9000"); - const uidField = await $('>>>input[name="uidField"]'); - await uidField.setValue('ken@goauthentik.io'); + let start = Date.now(); + for ([command, ...args] of login) { + await $AkSel[command].apply($, args); + } - const next1 = await $('>>>button[type="submit"]'); - await next1.click(); - await browser.pause(CLICK_TIME_DELAY); - - const pwdField = await $('>>>input[name="password"]'); - await pwdField.setValue('eat10bugs'); - const next2 = await $('>>>button[type="submit"]'); - await next2.click(); - await browser.pause(CLICK_TIME_DELAY); - - const home = await $('>>>div.header h1'); - expect(home).toHaveText('My applications'); + const home = await $(">>>div.header h1"); + expect(home).toHaveText("My applications"); const goToAdmin = await $('>>>a[href="/if/admin"]'); goToAdmin.click(); - await $('>>>ak-admin-overview').waitForDisplayed(); + await $(">>>ak-admin-overview").waitForDisplayed(); + $AkSel.button('>>>a[href="#/core/applications;%7B%22createForm%22%3Atrue%7D"]'); - const applicationLink = await $('>>>a[href="#/core/applications;%7B%22createForm%22%3Atrue%7D"]'); - applicationLink.click(); + await $(">>>ak-application-list").waitForDisplayed(); + $AkSel.button('>>>ak-wizard-frame button[slot="trigger"]'); - await $('>>>ak-application-list').waitForDisplayed(); - const startWizard = await $('>>>ak-wizard-frame button[slot="trigger"]') - startWizard.click(); - - { - const nameInput = await $('>>>ak-form-element-horizontal input[name="name"]'); - await nameInput.setValue('This Is My Application'); - - const slugInput = await $('>>>ak-form-element-horizontal input[name="slug"]'); - await slugInput.setValue('this-is-my-application'); - - const nextButton = await $('>>>ak-wizard-frame footer button.pf-m-primary'); - await nextButton.click(); + for ([command, ...args] of simpleApplication) { + await $AkSel[command].apply($, args); } - { - const input = await $('>>>input[value="proxyprovider-proxy"]'); - await input.click(); - - const nextButton = await $('>>>ak-wizard-frame footer button.pf-m-primary'); - await nextButton.click(); - } - - { - const input = await $('>>>ak-form-element-horizontal input[name="name"]'); - await input.setValue('This Is My Provider'); - } - - await browser.pause(2000); - }) -}) - + let timeTaken = Date.now() - start; + console.log("Total time taken : " + timeTaken + " milliseconds"); + }); +}); diff --git a/web/src/admin/applications/wizard/auth-method-choice/ak-application-wizard-authentication-method-choice.ts b/web/src/admin/applications/wizard/auth-method-choice/ak-application-wizard-authentication-method-choice.ts index da9a50996..6891b3c12 100644 --- a/web/src/admin/applications/wizard/auth-method-choice/ak-application-wizard-authentication-method-choice.ts +++ b/web/src/admin/applications/wizard/auth-method-choice/ak-application-wizard-authentication-method-choice.ts @@ -27,6 +27,12 @@ export class ApplicationWizardAuthenticationMethodChoice extends BasePanel { this.dispatchWizardUpdate({ providerModel: target.value }); } + validator() { + const radios = Array.from(this.form.querySelectorAll('input[type="radio"]')); + const chosen = radios.find((radio: Element) => radio instanceof HTMLInputElement && radio.checked); + return chosen; + } + renderProvider(type: LocalTypeCreate) { const method = this.wizard.providerModel;