mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-07 07:16:54 +00:00
# Which Problems Are Solved - The previous monorepo in monorepo structure for the login app and its related packages was fragmented, complicated and buggy. - The process for building and testing the login container was inconsistent between local development and CI. - Lack of clear documentation as well as easy and reliable ways for non-frontend developers to reproduce and fix failing PR checks locally. # How the Problems Are Solved - Consolidated the login app and its related npm packages by moving the main package to `apps/login/apps/login` and merging `apps/login/packages/integration` and `apps/login/packages/acceptance` into the main `apps/login` package. - Migrated from Docker Compose-based test setups to dev container-based setups, adding support for multiple dev container configurations: - `.devcontainer/base` - `.devcontainer/turbo-lint-unit` - `.devcontainer/turbo-lint-unit-debug` - `.devcontainer/login-integration` - `.devcontainer/login-integration-debug` - Added npm scripts to run the new dev container setups, enabling exact reproduction of GitHub PR checks locally, and updated the pipeline to use these containers. - Cleaned up Dockerfiles and docker-bake.hcl files to only build the production image for the login app. - Cleaned up compose files to focus on dev environments in dev containers. - Updated `CONTRIBUTING.md` with guidance on running and debugging PR checks locally using the new dev container approach. - Introduced separate Dockerfiles for the login app to distinguish between using published client packages and building clients from local protos. - Ensured the login container is always built in the pipeline for use in integration and acceptance tests. - Updated Makefile and GitHub Actions workflows to use `--frozen-lockfile` for installing pnpm packages, ensuring reproducible installs. - Disabled GitHub release creation by the changeset action. - Refactored the `/build` directory structure for clarity and maintainability. - Added a `clean` command to `docks/package.json`. - Experimentally added `knip` to the `zitadel-client` package for improved linting of dependencies and exports. # Additional Changes - Fixed Makefile commands for consistency and reliability. - Improved the structure and clarity of the `/build` directory to support seamless integration of the login build. - Enhanced documentation and developer experience for running and debugging CI checks locally. # Additional Context - See updated `CONTRIBUTING.md` for new local development and debugging instructions. - These changes are a prerequisite for further improvements to the CI pipeline and local development workflow. - Closes #10276
99 lines
3.3 KiB
TypeScript
99 lines
3.3 KiB
TypeScript
import { expect, Page } from "@playwright/test";
|
|
import { getCodeFromSink } from "./sink";
|
|
|
|
const codeField = "code-text-input";
|
|
const passwordField = "password-text-input";
|
|
const passwordChangeField = "password-change-text-input";
|
|
const passwordChangeConfirmField = "password-change-confirm-text-input";
|
|
const passwordSetField = "password-set-text-input";
|
|
const passwordSetConfirmField = "password-set-confirm-text-input";
|
|
const lengthCheck = "length-check";
|
|
const symbolCheck = "symbol-check";
|
|
const numberCheck = "number-check";
|
|
const uppercaseCheck = "uppercase-check";
|
|
const lowercaseCheck = "lowercase-check";
|
|
const equalCheck = "equal-check";
|
|
|
|
const matchText = "Matches";
|
|
const noMatchText = "Doesn't match";
|
|
|
|
export async function changePasswordScreen(page: Page, password1: string, password2: string) {
|
|
await page.getByTestId(passwordChangeField).pressSequentially(password1);
|
|
await page.getByTestId(passwordChangeConfirmField).pressSequentially(password2);
|
|
}
|
|
|
|
export async function passwordScreen(page: Page, password: string) {
|
|
await page.getByTestId(passwordField).pressSequentially(password);
|
|
}
|
|
|
|
export async function passwordScreenExpect(page: Page, password: string) {
|
|
await expect(page.getByTestId(passwordField)).toHaveValue(password);
|
|
await expect(page.getByTestId("error").locator("div")).toContainText("Failed to authenticate.");
|
|
}
|
|
|
|
export async function changePasswordScreenExpect(
|
|
page: Page,
|
|
password1: string,
|
|
password2: string,
|
|
length: boolean,
|
|
symbol: boolean,
|
|
number: boolean,
|
|
uppercase: boolean,
|
|
lowercase: boolean,
|
|
equals: boolean,
|
|
) {
|
|
await expect(page.getByTestId(passwordChangeField)).toHaveValue(password1);
|
|
await expect(page.getByTestId(passwordChangeConfirmField)).toHaveValue(password2);
|
|
|
|
await checkComplexity(page, length, symbol, number, uppercase, lowercase, equals);
|
|
}
|
|
|
|
async function checkComplexity(
|
|
page: Page,
|
|
length: boolean,
|
|
symbol: boolean,
|
|
number: boolean,
|
|
uppercase: boolean,
|
|
lowercase: boolean,
|
|
equals: boolean,
|
|
) {
|
|
await checkContent(page, lengthCheck, length);
|
|
await checkContent(page, symbolCheck, symbol);
|
|
await checkContent(page, numberCheck, number);
|
|
await checkContent(page, uppercaseCheck, uppercase);
|
|
await checkContent(page, lowercaseCheck, lowercase);
|
|
await checkContent(page, equalCheck, equals);
|
|
}
|
|
|
|
async function checkContent(page: Page, testid: string, match: boolean) {
|
|
if (match) {
|
|
await expect(page.getByTestId(testid)).toContainText(matchText);
|
|
} else {
|
|
await expect(page.getByTestId(testid)).toContainText(noMatchText);
|
|
}
|
|
}
|
|
|
|
export async function resetPasswordScreen(page: Page, username: string, password1: string, password2: string) {
|
|
const c = await getCodeFromSink(username);
|
|
await page.getByTestId(codeField).pressSequentially(c);
|
|
await page.getByTestId(passwordSetField).pressSequentially(password1);
|
|
await page.getByTestId(passwordSetConfirmField).pressSequentially(password2);
|
|
}
|
|
|
|
export async function resetPasswordScreenExpect(
|
|
page: Page,
|
|
password1: string,
|
|
password2: string,
|
|
length: boolean,
|
|
symbol: boolean,
|
|
number: boolean,
|
|
uppercase: boolean,
|
|
lowercase: boolean,
|
|
equals: boolean,
|
|
) {
|
|
await expect(page.getByTestId(passwordSetField)).toHaveValue(password1);
|
|
await expect(page.getByTestId(passwordSetConfirmField)).toHaveValue(password2);
|
|
|
|
await checkComplexity(page, length, symbol, number, uppercase, lowercase, equals);
|
|
}
|