Files
authentik/web/tests/pageobjects/page.ts
Ken Sternberg 248fcdd1bf web: update tests for Chromedriver 131 (#12199)
* web: Add InvalidationFlow to Radius Provider dialogues

## What

- Bugfix: adds the InvalidationFlow to the Radius Provider dialogues
  - Repairs: `{"invalidation_flow":["This field is required."]}` message, which was *not* propagated
    to the Notification.
- Nitpick: Pretties `?foo=${true}` expressions: `s/\?([^=]+)=\$\{true\}/\1/`

## Note

Yes, I know I'm going to have to do more magic when we harmonize the forms, and no, I didn't add the
Property Mappings to the wizard, and yes, I know I'm going to have pain with the *new* version of
the wizard. But this is a serious bug; you can't make Radius servers with *either* of the current
dialogues at the moment.

* web: fix selector warnings in WebdriverIO

Despite the [promises made](https://webdriver.io/docs/selectors#deep-selectors) by the WebdriverIO
team, we are still getting a lot of warnings and "falling back to pre-BIDI behavior" messages
when we attempt to access ShadowDOM contexts without the "pierce" (`>>>`) syntax.  So I've put
it back wherever it occurred and the system now uses the BIDI controllers correctly.

* web: update to Chromedriver 131 breaks a lot of stuff

This annoying bit of janitorial work cleans up the failure messages and resolution bugs
that arose when updating to the latest version of Chrome.  Keeping track of all the
weakness and breakage while the in-browser testing teams figure out how to live with
the ShadowDOM is just really time-consuming.
2024-12-02 08:19:51 -08:00

63 lines
2.4 KiB
TypeScript

import { browser } from "@wdio/globals";
import { Key } from "webdriverio";
const CLICK_TIME_DELAY = 250;
/**
* Main page object containing all methods, selectors and functionality that is shared across all
* page objects
*/
export default class Page {
/**
* Opens a sub page of the page
* @param path path of the sub page (e.g. /path/to/page.html)
*/
public async open(path: string) {
return await browser.url(`http://localhost:9000/${path}`);
}
public async pause(selector?: string) {
if (selector) {
return await $(selector).waitForDisplayed();
}
return await browser.pause(CLICK_TIME_DELAY);
}
/**
* Target a specific entry in SearchSelect. Requires that the SearchSelect have the `name`
* attribute set, so that the managed selector can find the *right* SearchSelect if there are
* multiple open SearchSelects on the board. See `./ldap-form.view:LdapForm.setBindFlow` for an
* example, and see `./oauth-form.view:OauthForm:setAuthorizationFlow` for a further example of
* why it would be hard to simplify this further (`flow` vs `tentanted-flow` vs a straight-up
* SearchSelect each have different a `searchSelector`).
*/
async searchSelect(searchSelector: string, managedSelector: string, buttonSelector: string) {
const inputBind = await $(searchSelector);
const inputMain = await inputBind.$('>>>input[type="text"]');
await inputMain.click();
const searchBlock = await (
await $(`>>>div[data-managed-for="${managedSelector}"]`).$(">>>ak-list-select")
).$$(">>>button");
let target: WebdriverIO.Element;
// @ts-expect-error "Types break on shadow$$"
for (const button of searchBlock) {
if ((await button.getText()).includes(buttonSelector)) {
target = button;
break;
}
}
// @ts-expect-error "TSC cannot tell if the `for` loop actually performs the assignment."
if (!target) {
throw new Error(`Expected to find an entry matching the spec ${buttonSelector}`);
}
await (await target).click();
await browser.keys(Key.Tab);
}
public async logout() {
await browser.url("http://localhost:9000/flows/-/default/invalidation/");
return await this.pause();
}
}