From f9f849574b32243a0b49fcc7a8707b73ec745ffc Mon Sep 17 00:00:00 2001 From: Ken Sternberg Date: Wed, 23 Oct 2024 10:50:27 -0700 Subject: [PATCH] We have working tests!!!!!! --- .../admin/common/ak-flow-search/FlowSearch.ts | 3 +- web/tests/pageobjects/controls.ts | 80 ++++++++++--------- web/tests/specs/oauth-provider.ts | 31 ++++++- 3 files changed, 73 insertions(+), 41 deletions(-) diff --git a/web/src/admin/common/ak-flow-search/FlowSearch.ts b/web/src/admin/common/ak-flow-search/FlowSearch.ts index 960c0f8099..74ccd212ac 100644 --- a/web/src/admin/common/ak-flow-search/FlowSearch.ts +++ b/web/src/admin/common/ak-flow-search/FlowSearch.ts @@ -7,6 +7,7 @@ import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter" import { html } from "lit"; import { property, query } from "lit/decorators.js"; +import { ifDefined } from "lit/directives/if-defined.js"; import { FlowsApi, FlowsInstancesListDesignationEnum } from "@goauthentik/api"; import type { Flow, FlowsInstancesListRequest } from "@goauthentik/api"; @@ -122,7 +123,7 @@ export class FlowSearch extends CustomListenerElement(AKElement) .renderElement=${renderElement} .renderDescription=${renderDescription} .value=${getFlowValue} - .name=${this.name} + name=${ifDefined(this.name)} @ak-change=${this.handleSearchUpdate} ?blankable=${!this.required} > diff --git a/web/tests/pageobjects/controls.ts b/web/tests/pageobjects/controls.ts index ba1dcafce7..d84710a236 100644 --- a/web/tests/pageobjects/controls.ts +++ b/web/tests/pageobjects/controls.ts @@ -1,6 +1,6 @@ import { browser } from "@wdio/globals"; import { match } from "ts-pattern"; -import { ChainablePromiseArray, Key } from "webdriverio"; +import { Key } from "webdriverio"; export async function setSearchSelect(name: string, value: string) { const control = await (async () => { @@ -21,23 +21,22 @@ export async function setSearchSelect(name: string, value: string) { await input.scrollIntoView(); await input.click(); - // Weirdly necessary because it's portals! - const searchBlock = await ( - await $(`div[data-managed-for*="${name}"]`).$("ak-list-select") - ).shadow$$("button"); - // @ts-expect-error "Types break on shadow$$" - for (const button of searchBlock) { - if ((await button.getText()).includes(value)) { - target = button; - break; + const button = await (async () => { + for await (const button of $(`div[data-managed-for*="${name}"]`) + .$("ak-list-select") + .$$("button")) { + if ((await button.getText()).includes(value)) { + return button; + } } - } + })(); + // @ts-expect-error "TSC cannot tell if the `for` loop actually performs the assignment." - if (!target) { + if (!button.isExisting()) { throw new Error(`Expected to find an entry matching the spec ${value}`); } - await (await target).click(); + await (await button).click(); await browser.keys(Key.Tab); } @@ -55,35 +54,44 @@ export async function setRadio(name: string, value: string) { await item.click(); } -browser.addCommand( - "findInside$", - async function (these: WebdriverIO.ElementArray, selector: string) { - // prettier-ignore - console.log("HERE!!!!!!!!!"); - for await (const item of these) { - const wanted = item.$(selector); - if (wanted.isExisting()) { - return wanted; - } - } - return undefined; - }, - true, -); - -export async function setTypeCreate(name: string, value: string) { +export async function setTypeCreate(name: string, value: string | RegExp) { const control = await $(`ak-wizard-page-type-create[name="${name}"]`); await control.scrollIntoView(); - const selection = await $$("ak-type-create-grid-card").findInside$(`div*=${value}`); - await selection.scrollIntoView(); - await selection.click(); + + const comparator = + typeof value === "string" ? (sample) => sample === value : (sample) => value.test(sample); + + const card = await (async () => { + for await (const card of $("ak-wizard-page-type-create").$$( + '[data-ouid-component-type="ak-type-create-grid-card"]', + )) { + if (comparator(await card.$(".pf-c-card__title").getText())) { + return card; + } + } + })(); + + await card.scrollIntoView(); + await card.click(); } -export async function setFormGroup(name: string, setting: "open" | "closed") { - const formGroup = await $(`.//span[contains(., "${name}")]`); +export async function setFormGroup(name: string | RegExp, setting: "open" | "closed") { + const comparator = + typeof name === "string" ? (sample) => sample === name : (sample) => name.test(sample); + + const formGroup = await (async () => { + for await (const group of $$("ak-form-group")) { + if ( + comparator(await group.$("div.pf-c-form__field-group-header-title-text").getText()) + ) { + return group; + } + } + })(); + await formGroup.scrollIntoView(); const toggle = await formGroup.$("div.pf-c-form__field-group-toggle-button button"); - await match([toggle.getAttribute("expanded"), setting]) + await match([await toggle.getAttribute("aria-expanded"), setting]) .with(["false", "open"], async () => await toggle.click()) .with(["true", "closed"], async () => await toggle.click()) .otherwise(async () => {}); diff --git a/web/tests/specs/oauth-provider.ts b/web/tests/specs/oauth-provider.ts index 0cb5393986..9465959ff4 100644 --- a/web/tests/specs/oauth-provider.ts +++ b/web/tests/specs/oauth-provider.ts @@ -32,19 +32,19 @@ async function fillOutFields(fields: FieldDesc[]) { } describe("Configure Oauth2 Providers", () => { - it("Should configure a simple LDAP Application", async () => { + it("Should configure a simple OAuth2 Provider", async () => { const newProviderName = `New OAuth2 Provider - ${randomId()}`; await reachTheProvider(); await $("ak-wizard-page-type-create").waitForDisplayed(); - await setTypeCreate("selectProviderType", "OAuth2/OpenID Provider"); - await clickButton("Next"); // prettier-ignore await fillOutFields([ + [setTypeCreate, "selectProviderType", "OAuth2/OpenID Provider"], + [clickButton, "Next"], [setTextInput, "name", newProviderName], - [setFormGroup, "Flow settings", "open"], + [setFormGroup, /Flow settings/, "open"], [setSearchSelect, "authenticationFlow", "default-authentication-flow"], [setSearchSelect, "authorizationFlow", "default-provider-authorization-explicit-consent"], [setSearchSelect, "invalidationFlow", "default-invalidation-flow"], @@ -54,3 +54,26 @@ describe("Configure Oauth2 Providers", () => { await ProviderWizardView.nextButton.click(); }); }); + +describe("Configure LDAP Providers", () => { + it("Should configure a simple LDAP Provider", async () => { + const newProviderName = `New LDAP Provider - ${randomId()}`; + + await reachTheProvider(); + await $("ak-wizard-page-type-create").waitForDisplayed(); + + // prettier-ignore + await fillOutFields([ + [setTypeCreate, "selectProviderType", "LDAP Provider"], + [clickButton, "Next"], + [setTextInput, "name", newProviderName], + [setFormGroup, /Flow settings/, "open"], + // This will never not weird me out. + [setSearchSelect, "authorizationFlow", "default-authentication-flow"], + [setSearchSelect, "invalidationFlow", "default-invalidation-flow"], + ]); + + await ProviderWizardView.pause(); + await ProviderWizardView.nextButton.click(); + }); +});