acceptance

This commit is contained in:
Elio Bischof
2025-06-09 10:36:36 +02:00
parent f5e82f418e
commit 895855e1fa
100 changed files with 239 additions and 155 deletions

View File

@@ -1,7 +1,13 @@
LOGIN_DEPENDENCIES_TAG ?= "zitadel-login-dependencies:local"
LOGIN_IMAGE_TAG ?= "zitadel-login:local"
CORE_MOCK_TAG ?= "zitadel-core-mock:local"
LOGIN_INTEGRATION_TESTSUITE_TAG ?= "zitadel-login-integration-testsuite:local"
export LOGIN_IMAGE_TAG ?= zitadel-login:local
LOGIN_LINT_TAG ?= zitadel-login-lint:local
LOGIN_DEPENDENCIES_TAG ?= zitadel-login-dependencies:local
LOGIN_TEST_UNIT_TAG ?= zitadel-login-lint:local
export CORE_MOCK_TAG ?= zitadel-core-mock:local
export LOGIN_TEST_INTEGRATION_TAG ?= zitadel-login-test-integration:local
export LOGIN_TEST_ACCEPTANCE_SETUP_TAG := zitadel-login-test-acceptance-setup:local
export LOGIN_TEST_ACCEPTANCE_POSTGRES_TAG := postgres:17.0-alpine3.19
export LOGIN_TEST_ACCEPTANCE_GOLANG_TAG := golang:1.24-alpine
export ZITADEL_IMAGE_TAG ?= ghcr.io/zitadel/zitadel:latest
XDG_CACHE_HOME ?= $(HOME)/.cache
export CACHE_DIR ?= $(XDG_CACHE_HOME)/zitadel-make
@@ -12,8 +18,8 @@ login-help:
@echo "Available targets:"
@echo " login-help - Show this help message."
@echo " login-lint - Run linting and formatting checks. FORCE=true prevents skipping."
@echo " login-unit - Run unit tests. FORCE=true prevents skipping."
@echo " login-integration - Run integration tests. FORCE=true prevents skipping."
@echo " login-test-unit - Run unit tests. FORCE=true prevents skipping."
@echo " login-test-integration - Run integration tests. FORCE=true prevents skipping."
@echo " login-standalone-build - Build the docker image for production login containers."
@echo " login-quality - Run all quality checks (login-lint, login-unit, login-integration)."
@echo " login-ci - Run all CI tasks. Run it with the -j flag to parallelize: make -j ci."
@@ -21,51 +27,65 @@ login-help:
@echo " clean-cache-keys - Remove all cache keys."
login-lint-run: login-dependencies
docker run --rm $(LOGIN_DEPENDENCIES_TAG) lint
docker run --rm $(LOGIN_DEPENDENCIES_TAG) format --check
login-lint-run:
docker run --rm $(LOGIN_LINT_TAG) lint
docker run --rm $(LOGIN_LINT_TAG) format --check
.PHONY: login-lint
login-lint:
./scripts/run_or_skip.sh login-lint-run $(LOGIN_DEPENDENCIES_TAG)
login-lint: login-lint-build
./scripts/run_or_skip.sh login-lint-run $(LOGIN_LINT_TAG)
login-unit-run: login-dependencies
docker run --rm $(LOGIN_DEPENDENCIES_TAG) test:unit
login-test-unit-run:
docker run --rm $(LOGIN_TEST_UNIT_TAG) test:unit:standalone
.PHONY: login-unit
login-unit:
./scripts/run_or_skip.sh login-unit-run $(LOGIN_DEPENDENCIES_TAG)
.PHONY: login-test-unit
login-test-unit: login-test-unit-build
./scripts/run_or_skip.sh login-test-unit-run $(LOGIN_TEST_UNIT_TAG)
login-integration-run: login-standalone-build core-mock-build login-integration-testsuite-build
docker compose --file ./apps/login-integration-testsuite/docker-compose.yaml run --rm integration-testsuite
login-test-integration-run:
docker compose --file ./apps/login-test-integration/docker-compose.yaml run --rm login-test-integration
.PHONY: login-integration
login-integration:
./scripts/run_or_skip.sh login-integration-run '$(LOGIN_IMAGE_TAG);$(LOGIN_INTEGRATION_TESTSUITE_TAG);$(CORE_MOCK_TAG)'
.PHONY: login-test-integration
login-test-integration: login-standalone-build login-test-integration-build
./scripts/run_or_skip.sh login-test-integration-run "$(LOGIN_IMAGE_TAG);$(CORE_MOCK_TAG);$(LOGIN_TEST_INTEGRATION_TAG)"
login-test-acceptance-run:
docker compose --file ./apps/login-test-acceptance/saml/docker-compose.yaml up --detach samlsp
docker compose --file ./apps/login-test-acceptance/oidc/docker-compose.yaml up --detach oidcrp
docker compose --file ./apps/login-test-acceptance/docker-compose.yaml run login-test-acceptance
login-test-acceptance: login-standalone-build login-test-acceptance-build
./scripts/run_or_skip.sh login-test-acceptance-run "$(LOGIN_IMAGE_TAG);$(LOGIN_TEST_ACCEPTANCE_SETUP_TAG);$(LOGIN_TEST_ACCEPTANCE_POSTGRES_TAG);$(LOGIN_TEST_ACCEPTANCE_GOLANG_TAG)"
.PHONY: login-quality
login-quality: core-mock-build login-quality-after-build
login-quality-after-build: login-lint login-unit login-integration
login-quality: login-lint login-test-unit login-test-integration
@:
.PHONY: login-ci
login-ci: core-mock-build login-ci-after-build
login-ci-after-build: login-quality-after-build login-standalone-build
login-ci: login-quality login-standalone-build
@:
login-dependencies:
login-dependencies-build:
docker buildx bake login-dependencies --set login-dependencies.tags=$(LOGIN_DEPENDENCIES_TAG);
login-lint-build:
docker buildx bake login-lint --set login-lint.tags=$(LOGIN_LINT_TAG);
login-test-unit-build:
docker buildx bake login-test-unit --set login-test-unit.tags=$(LOGIN_TEST_UNIT_TAG);
login-test-integration-build:
docker buildx bake core-mock --set core-mock.tags=$(CORE_MOCK_TAG);
docker buildx bake login-test-integration --set login-test-integration.tags=$(LOGIN_TEST_INTEGRATION_TAG)
login-test-acceptance-build:
# TODO: Prebuild sink, saml and oidc
docker buildx bake --pull --file apps/login-test-acceptance/docker-compose.yaml --set setup.context=apps/login-test-acceptance
.PHONY: login-standalone-build
login-standalone-build:
docker buildx bake login-standalone --set login-standalone.tags=$(LOGIN_IMAGE_TAG);
core-mock-build:
docker buildx bake core-mock --set core-mock.tags=$(CORE_MOCK_TAG);
login-integration-testsuite-build: login-dependencies
docker buildx bake login-integration-testsuite --set login-integration-testsuite.tags=$(LOGIN_INTEGRATION_TESTSUITE_TAG)
.PHONY: clean-cache-keys
clean-cache-keys:
@echo "Removing cache directory: $(CACHE_DIR)"

View File

@@ -1,7 +1,8 @@
services:
zitadel:
user: "${ZITADEL_DEV_UID}"
image: "${ZITADEL_IMAGE:-ghcr.io/zitadel/zitadel:02617cf17fdde849378c1a6b5254bbfb2745b164}"
image: "${ZITADEL_IMAGE:-ghcr.io/zitadel/zitadel:latest}"
pull_policy: always
command: 'start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled --config /zitadel.yaml --steps /zitadel.yaml'
ports:
- "8080:8080"
@@ -16,7 +17,7 @@ services:
db:
restart: "always"
image: postgres:17.0-alpine3.19
image: ${LOGIN_TEST_ACCEPTANCE_POSTGES_TAG:-postgres:17.0-alpine3.19}
environment:
- POSTGRES_USER=zitadel
- PGUSER=zitadel
@@ -41,7 +42,10 @@ services:
setup:
user: "${ZITADEL_DEV_UID}"
container_name: setup
build: .
build:
context: .
tags:
- ${LOGIN_TEST_ACCEPTANCE_SETUP_TAG:-zitadel-login-test-acceptance-setup:local}
environment:
PAT_FILE: /pat/zitadel-admin-sa.pat
ZITADEL_API_INTERNAL_URL: http://zitadel:8080
@@ -59,7 +63,7 @@ services:
condition: "service_completed_successfully"
sink:
image: golang:1.24-alpine
image: ${LOGIN_TEST_ACCEPTANCE_GOLANG_TAG:-golang:1.24-alpine}
container_name: sink
command: go run /sink/main.go -port '3333' -email '/email' -sms '/sms' -notification '/notification'
ports:
@@ -69,3 +73,10 @@ services:
depends_on:
setup:
condition: "service_completed_successfully"
login-test-acceptance:
image: "${LOGIN_TEST_ACCEPTANCE_TAG:-zitadel-login-test-acceptance:local}"
container_name: login-test-acceptance
depends_on:
sink:
condition: service_started

View File

@@ -0,0 +1,22 @@
{
"name": "login-test-acceptance",
"private": true,
"scripts": {
"test:acceptance": "pnpm exec playwright test",
"run-zitadel": "docker compose -f ./acceptance/docker-compose.yaml run setup",
"run-sink": "docker compose -f ./acceptance/docker-compose.yaml up -d sink",
"run-samlsp": "docker compose -f ./acceptance/saml/docker-compose.yaml up -d",
"run-samlidp": "docker compose -f ./acceptance/idp/saml/docker-compose.yaml up -d",
"run-oidcrp": "docker compose -f ./acceptance/oidc/docker-compose.yaml up -d",
"run-oidcop": "docker compose -f ./acceptance/idp/oidc/docker-compose.yaml up -d",
"stop": "docker compose -f ./acceptance/docker-compose.yaml stop"
},
"devDependencies": {
"@otplib/core": "^12.0.0",
"@otplib/plugin-thirty-two": "^12.0.0",
"@otplib/plugin-crypto": "^12.0.0",
"@faker-js/faker": "^9.7.0",
"@playwright/test": "^1.52.0",
"typescript": "^5.8.3"
}
}

View File

@@ -1,13 +1,13 @@
services:
core-mock:
image: ${CORE_MOCK_TAG:-zitadel-core-mock:local}
image: "${CORE_MOCK_TAG:-zitadel-core-mock:local}"
container_name: core-mock
ports:
- 22220:22220
- 22222:22222
login:
image: ${LOGIN_IMAGE_TAG:-zitadel-login:local}
image: "${LOGIN_IMAGE_TAG:-zitadel-login:local}"
container_name: login
ports:
- 3000:3000
@@ -18,9 +18,9 @@ services:
- DEBUG=true
- NEXT_PUBLIC_BASE_PATH="/ui/v2/login"
integration-testsuite:
image: ${LOGIN_INTEGRATION_TESTSUITE_TAG:-zitadel-login-integration-testsuite:local}
container_name: integration-testsuite
login-test-integration:
image: "${LOGIN_TEST_INTEGRATION_TAG:-zitadel-login-test-integration:local}"
container_name: login-test-integration
environment:
- LOGIN_BASE_URL=http://login:3000/ui/v2/login
- CYPRESS_CORE_MOCK_STUBS_URL=http://core-mock:22220/v1/stubs

View File

@@ -53,8 +53,7 @@ describe("verify invite", () => {
resourceOwner: "220516472055706145",
},
sessionId: "221394658884845598",
sessionToken:
"SDMc7DlYXPgwRJ-Tb5NlLqynysHjEae3csWsKzoZWLplRji0AYY3HgAkrUEBqtLCvOayLJPMd0ax4Q",
sessionToken: "SDMc7DlYXPgwRJ-Tb5NlLqynysHjEae3csWsKzoZWLplRji0AYY3HgAkrUEBqtLCvOayLJPMd0ax4Q",
challenges: undefined,
},
});
@@ -94,10 +93,7 @@ describe("verify invite", () => {
stub("zitadel.user.v2.UserService", "VerifyInviteCode");
cy.visit("/verify?userId=221394658884845598&code=abc&invite=true");
cy.location("pathname", { timeout: 10_000 }).should(
"eq",
"/authenticator/set",
);
cy.location("pathname", { timeout: 10_000 }).should("eq", "/ui/v2/login/authenticator/set");
});
it("shows an error if invite code validation failed", () => {

View File

@@ -18,8 +18,7 @@ describe("login", () => {
resourceOwner: "220516472055706145",
},
sessionId: "221394658884845598",
sessionToken:
"SDMc7DlYXPgwRJ-Tb5NlLqynysHjEae3csWsKzoZWLplRji0AYY3HgAkrUEBqtLCvOayLJPMd0ax4Q",
sessionToken: "SDMc7DlYXPgwRJ-Tb5NlLqynysHjEae3csWsKzoZWLplRji0AYY3HgAkrUEBqtLCvOayLJPMd0ax4Q",
challenges: undefined,
},
});
@@ -96,7 +95,7 @@ describe("login", () => {
});
it("should redirect a user with password authentication to /password", () => {
cy.visit("/loginname?loginName=john%40zitadel.com&submit=true");
cy.location("pathname", { timeout: 10_000 }).should("eq", "/password");
cy.location("pathname", { timeout: 10_000 }).should("eq", "/ui/v2/login/password");
});
describe("with passkey prompt", () => {
beforeEach(() => {
@@ -107,8 +106,7 @@ describe("login", () => {
changeDate: "2023-07-04T07:58:20.126Z",
resourceOwner: "220516472055706145",
},
sessionToken:
"SDMc7DlYXPgwRJ-Tb5NlLqynysHjEae3csWsKzoZWLplRji0AYY3HgAkrUEBqtLCvOayLJPMd0ax4Q",
sessionToken: "SDMc7DlYXPgwRJ-Tb5NlLqynysHjEae3csWsKzoZWLplRji0AYY3HgAkrUEBqtLCvOayLJPMd0ax4Q",
challenges: undefined,
},
});
@@ -168,7 +166,7 @@ describe("login", () => {
it("should redirect a user with passwordless authentication to /passkey", () => {
cy.visit("/loginname?loginName=john%40zitadel.com&submit=true");
cy.location("pathname", { timeout: 10_000 }).should("eq", "/passkey");
cy.location("pathname", { timeout: 10_000 }).should("eq", "/ui/v2/login/passkey");
});
});
});

View File

@@ -33,8 +33,7 @@ describe("register", () => {
resourceOwner: "220516472055706145",
},
sessionId: "221394658884845598",
sessionToken:
"SDMc7DlYXPgwRJ-Tb5NlLqynysHjEae3csWsKzoZWLplRji0AYY3HgAkrUEBqtLCvOayLJPMd0ax4Q",
sessionToken: "SDMc7DlYXPgwRJ-Tb5NlLqynysHjEae3csWsKzoZWLplRji0AYY3HgAkrUEBqtLCvOayLJPMd0ax4Q",
challenges: undefined,
},
});
@@ -65,12 +64,10 @@ describe("register", () => {
cy.visit("/register");
cy.get('input[data-testid="firstname-text-input"]').focus().type("John");
cy.get('input[data-testid="lastname-text-input"]').focus().type("Doe");
cy.get('input[data-testid="email-text-input"]')
.focus()
.type("john@zitadel.com");
cy.get('input[data-testid="email-text-input"]').focus().type("john@zitadel.com");
cy.get('input[type="checkbox"][value="privacypolicy"]').check();
cy.get('input[type="checkbox"][value="tos"]').check();
cy.get('button[type="submit"]').click();
cy.location("pathname", { timeout: 10_000 }).should("eq", "/passkey/set");
cy.location("pathname", { timeout: 10_000 }).should("eq", "/ui/v2/login/passkey/set");
});
});

View File

@@ -55,8 +55,7 @@ describe("verify email", () => {
resourceOwner: "220516472055706145",
},
sessionId: "221394658884845598",
sessionToken:
"SDMc7DlYXPgwRJ-Tb5NlLqynysHjEae3csWsKzoZWLplRji0AYY3HgAkrUEBqtLCvOayLJPMd0ax4Q",
sessionToken: "SDMc7DlYXPgwRJ-Tb5NlLqynysHjEae3csWsKzoZWLplRji0AYY3HgAkrUEBqtLCvOayLJPMd0ax4Q",
challenges: undefined,
},
});

View File

@@ -1,12 +1,12 @@
{
"name": "login-integration-testsuite",
"name": "login-test-integration",
"private": true,
"scripts": {
"test:integration": "pnpm exec concurrently --names 'mock,test' --success command-test --kill-others 'pnpm:mock' 'env-cmd -f ./.env.integration start-server-and-test start http://localhost:3000 \"test:integration:run\"'",
"test:integration:watch:run": "pnpm exec concurrently --names 'mock,test' --kill-others 'pnpm:mock' 'env-cmd -f ./.env.integration start-server-and-test dev http://localhost:3000 \"pnpm nodemon -e js,jsx,ts,tsx,css,scss --ignore \\\"__test__/**\\\" --exec \\\"pnpm test:integration:run\\\"\"'",
"test:integration:watch:open": "pnpm exec concurrently --names 'mock,test' --kill-others 'pnpm:mock' 'env-cmd -f ./.env.integration start-server-and-test dev http://localhost:3000 \"pnpm nodemon -e js,jsx,ts,tsx,css,scss --ignore \\\"__test__/**\\\" --exec \\\"pnpm test:integration:open\\\"\"'",
"test:integration:run": "pnpm exec cypress run --config-file ./cypress/cypress.config.ts --quiet",
"test:integration:open": "pnpm exec cypress open --config-file ./cypress/cypress.config.ts",
"test:integration:run": "pnpm exec cypress run --quiet",
"test:integration:open": "pnpm exec cypress open",
"mock": "pnpm mock:stop && docker run --rm --name zitadel-mock-grpc-server --publish 22220:22220 --publish 22222:22222 ${CORE_MOCK_TAG:-zitadel-core-mock:local}",
"mock:stop": "docker rm --force zitadel-mock-grpc-server 2>/dev/null || true"
},

View File

@@ -1,4 +1,4 @@
const url = Cypress.env('CORE_MOCK_STUBS_URL') || "http://localhost:22220/v1/stubs"
const url = Cypress.env("CORE_MOCK_STUBS_URL") || "http://localhost:22220/v1/stubs";
function removeStub(service: string, method: string) {
return cy.request({

View File

@@ -5,6 +5,7 @@
"scripts": {
"dev": "pnpm exec next dev --turbopack",
"test:unit": "pnpm exec vitest",
"test:unit:standalone": "pnpm test:unit",
"test:unit:watch": "pnpm test:unit --watch",
"lint": "pnpm exec next lint && pnpm exec prettier --check .",
"lint:fix": "pnpm exec prettier --write .",

View File

@@ -14,6 +14,7 @@
"test:unit": {
"dependsOn": ["@zitadel/client#build"]
},
"test:unit:standalone": {},
"test:watch": {
"dependsOn": ["@zitadel/client#build"]
}

View File

@@ -6,17 +6,33 @@ target "login-platform" {
dockerfile = "dockerfiles/login-platform.Dockerfile"
}
target "login-base" {
dockerfile = "dockerfiles/login-base.Dockerfile"
target "login-pnpm" {
dockerfile = "dockerfiles/login-pnpm.Dockerfile"
contexts = {
login-platform = "target:login-platform"
login-platform = "target:login-platform"
}
}
target "login-dependencies" {
dockerfile = "dockerfiles/login-dependencies.Dockerfile"
target "login-dev-base" {
dockerfile = "dockerfiles/login-dev-base.Dockerfile"
contexts = {
login-base = "target:login-base"
login-pnpm = "target:login-pnpm"
}
}
target "login-lint" {
dockerfile = "dockerfiles/login-lint.Dockerfile"
contexts = {
login-dev-base = "target:login-dev-base"
}
}
target "login-test-unit" {
dockerfile = "dockerfiles/login-test-unit.Dockerfile"
contexts = {
login-pnpm = "target:login-pnpm"
login-dev-base = "target:login-dev-base"
typescript-proto-client = "target:typescript-proto-client"
}
}
@@ -24,7 +40,7 @@ target "typescript-proto-client" {
dockerfile = "dockerfiles/typescript-proto-client.Dockerfile"
contexts = {
# We directly generate and download the client server-side with buf, so we don't need the proto files
login-base = "target:login-dependencies"
login-pnpm = "target:login-pnpm"
}
}
@@ -33,7 +49,7 @@ target "typescript-proto-client" {
target "proto-files" {
dockerfile = "dockerfiles/proto-files.Dockerfile"
contexts = {
login-base = "target:login-dependencies"
login-pnpm = "target:login-pnpm"
}
}
@@ -44,13 +60,22 @@ target "core-mock" {
}
}
target "login-integration-testsuite" {
dockerfile = "dockerfiles/login-integration-testsuite.Dockerfile"
target "login-test-integration" {
dockerfile = "dockerfiles/login-test-integration.Dockerfile"
contexts = {
login-base = "target:login-base"
login-pnpm = "target:login-pnpm"
}
}
target "login-test-acceptance" {
context = "apps/login-test-acceptance"
contexts = {
login-pnpm = "target:login-pnpm"
login-test-acceptance-setup = "login-test-acceptance-setup:latest"
}
}
# We run integration and acceptance tests against the next standalone server for docker.
target "login-standalone" {
dockerfile = "dockerfiles/login-standalone.Dockerfile"
@@ -59,6 +84,6 @@ target "login-standalone" {
}
contexts = {
login-platform = "target:login-platform"
login-base = "target:login-dependencies"
login-pnpm = "target:login-pnpm"
}
}

View File

@@ -1,18 +0,0 @@
FROM login-base AS login-dependencies
COPY \
turbo.json \
.npmrc \
package.json \
pnpm-lock.yaml \
pnpm-workspace.yaml \
./
COPY packages/zitadel-client/package.json ./packages/zitadel-client/
COPY packages/zitadel-eslint-config/package.json ./packages/zitadel-eslint-config/
COPY packages/zitadel-prettier-config/package.json ./packages/zitadel-prettier-config/
COPY packages/zitadel-proto/package.json ./packages/zitadel-proto/
COPY packages/zitadel-tailwind-config/package.json ./packages/zitadel-tailwind-config/
COPY packages/zitadel-tsconfig/package.json ./packages/zitadel-tsconfig/
COPY apps/login/package.json ./apps/login/
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
pnpm install --frozen-lockfile
ENTRYPOINT ["pnpm"]

View File

@@ -0,0 +1,9 @@
FROM login-pnpm AS login-dev-base
COPY \
turbo.json \
.npmrc \
package.json \
./
COPY apps/login/package.json ./apps/login/
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
pnpm install --frozen-lockfile --filter . --filter=apps/login

View File

@@ -1,16 +0,0 @@
FROM login-base AS integration-dependencies
COPY \
pnpm-lock.yaml \
pnpm-workspace.yaml \
./
COPY ./apps/login-integration-testsuite/package.json ./apps/login-integration-testsuite/package.json
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
pnpm install --no-frozen-lockfile --filter=login-integration-testsuite
FROM cypress/factory AS login-integration-testsuite
WORKDIR /opt/app
COPY --from=integration-dependencies /build/apps/login-integration-testsuite .
RUN npm install cypress
RUN npx cypress install
COPY ./apps/login-integration-testsuite .
CMD ["npx", "cypress", "run"]

View File

@@ -0,0 +1,5 @@
FROM login-dev-base AS login-lint
COPY packages/zitadel-tsconfig packages/zitadel-tsconfig
COPY packages/zitadel-prettier-config packages/zitadel-prettier-config
COPY packages/zitadel-eslint-config packages/zitadel-eslint-config
COPY apps/login apps/login

View File

@@ -4,3 +4,11 @@ ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
RUN apk add --no-cache libc6-compat bash git
WORKDIR /build
COPY \
turbo.json \
.npmrc \
package.json \
pnpm-lock.yaml \
pnpm-workspace.yaml \
./
ENTRYPOINT ["pnpm"]

View File

@@ -1,8 +1,9 @@
FROM login-base AS prune-for-docker
FROM login-pnpm AS prune-for-docker
RUN pnpm install turbo --global
COPY . .
RUN turbo prune @zitadel/login --docker
FROM login-base AS installer
FROM login-pnpm AS installer
COPY --from=prune-for-docker /build/out/json/ .
RUN pnpm install --frozen-lockfile
COPY --from=prune-for-docker /build/out/full/ .

View File

@@ -0,0 +1,7 @@
FROM login-pnpm AS login-test-acceptance-dependencies
COPY ./apps/login-test-acceptance/package.json ./apps/login-test-acceptance/package.json
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
pnpm install --frozen-lockfile --filter=login-test-acceptance \
COPY ./apps/login-test-acceptance ./apps/login-test-acceptance
COPY --from=login-test-acceptance-setup / /
CMD ["pnpm", "test:acceptance"]

View File

@@ -0,0 +1,12 @@
FROM login-pnpm AS login-test-integration-dependencies
COPY ./apps/login-test-integration/package.json ./apps/login-test-integration/package.json
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
pnpm install --frozen-lockfile --filter=login-test-integration
FROM cypress/factory:5.10.0 AS login-test-integration
WORKDIR /opt/app
COPY --from=login-test-integration-dependencies /build/apps/login-test-integration .
COPY ./apps/login-test-integration .
RUN npm install cypress
RUN npx cypress install
CMD ["npx", "cypress", "run"]

View File

@@ -0,0 +1,14 @@
FROM login-pnpm AS zitadel-test-unit-build
COPY packages/zitadel-client/package.json ./packages/zitadel-client/
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
pnpm install --frozen-lockfile
COPY packages/zitadel-tsconfig packages/zitadel-tsconfig
WORKDIR /build/packages/zitadel-client
COPY packages/zitadel-client .
COPY --from=typescript-proto-client / /build/packages/zitadel-proto
RUN pnpm build
FROM login-dev-base AS zitadel-test-unit
COPY packages/zitadel-tsconfig packages/zitadel-tsconfig
COPY --from=zitadel-test-unit-build /build/packages/zitadel-client/dist /build/packages/zitadel-client/dist
COPY apps/login apps/login

View File

@@ -1,6 +1,9 @@
FROM login-base AS zitadel-proto
FROM login-pnpm AS zitadel-proto
COPY packages/zitadel-proto/package.json ./packages/zitadel-proto/
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
pnpm install --frozen-lockfile
COPY packages/zitadel-proto packages/zitadel-proto
RUN pnpm generate
FROM scratch
FROM scratch AS typescript-proto-client
COPY --from=zitadel-proto /build/packages/zitadel-proto /

View File

@@ -5,16 +5,16 @@
"scripts": {
"generate": "pnpm exec turbo run generate",
"build": "pnpm exec turbo run build",
"build:docker": "rm -rf ./out ./docker && pnpm exec turbo run build --filter=./packages/zitadel-client && pnpm exec turbo prune @zitadel/login --docker && mkdir -p ./docker && cd ./docker && cp -r ../out/json/* . && pnpm install --frozen-lockfile && cp -r ../out/full/* . && pnpm exec turbo run build:standalone && cd ..",
"build:packages": "pnpm exec turbo run build --filter=./packages/*",
"build:apps": "pnpm exec turbo run build --filter=./apps/*",
"test": "pnpm exec turbo run test",
"start": "pnpm exec turbo run start",
"start:built": "pnpm exec turbo run start:built",
"test:unit": "pnpm exec turbo run test:unit -- --passWithNoTests",
"test:unit:standalone": "pnpm exec turbo run test:unit:standalone",
"test:integration": "pnpm exec turbo run test:integration",
"test:integration:run": "pnpm exec turbo run test:integration:run",
"test:acceptance": "pnpm exec playwright test",
"test:acceptance": "pnpm exec turbo run test:integration:acceptance",
"test:watch": "pnpm exec turbo run test:watch",
"dev": "pnpm exec turbo run dev --no-cache --continue",
"lint": "pnpm exec turbo run lint",
@@ -24,14 +24,7 @@
"format": "pnpm exec prettier --check \"**/*.{ts,tsx,md}\"",
"changeset": "pnpm exec changeset",
"version-packages": "pnpm exec changeset version",
"release": "pnpm exec turbo run build --filter=login^... && pnpm exec changeset publish",
"run-zitadel": "docker compose -f ./acceptance/docker-compose.yaml run setup",
"run-sink": "docker compose -f ./acceptance/docker-compose.yaml up -d sink",
"run-samlsp": "docker compose -f ./acceptance/saml/docker-compose.yaml up -d",
"run-samlidp": "docker compose -f ./acceptance/idp/saml/docker-compose.yaml up -d",
"run-oidcrp": "docker compose -f ./acceptance/oidc/docker-compose.yaml up -d",
"run-oidcop": "docker compose -f ./acceptance/idp/oidc/docker-compose.yaml up -d",
"stop": "docker compose -f ./acceptance/docker-compose.yaml stop"
"release": "pnpm exec turbo run build --filter=login^... && pnpm exec changeset publish"
},
"pnpm": {
"overrides": {
@@ -39,13 +32,7 @@
}
},
"devDependencies": {
"@otplib/core": "^12.0.0",
"@otplib/plugin-thirty-two": "^12.0.0",
"@otplib/plugin-crypto": "^12.0.0",
"@faker-js/faker": "^9.7.0",
"@changesets/cli": "^2.29.2",
"@playwright/test": "^1.52.0",
"@types/node": "^22.14.1",
"@vitejs/plugin-react": "^4.4.1",
"@zitadel/prettier-config": "workspace:*",
"axios": "^1.8.4",

View File

@@ -44,9 +44,11 @@
"sideEffects": false,
"scripts": {
"build": "pnpm exec tsup",
"build:standalone": "pnpm build",
"test": "pnpm test:unit",
"test:watch": "pnpm test:unit:watch",
"test:unit": "pnpm exec vitest",
"test:unit:standalone": "pnpm test:unit",
"test:unit:watch": "pnpm exec vitest --watch",
"dev": "pnpm exec tsup --watch --dts",
"lint": "eslint \"src/**/*.ts*\"",

View File

@@ -4,10 +4,6 @@
"build": {
"outputs": ["dist/**"],
"dependsOn": ["@zitadel/proto#generate"]
},
"build:standalone": {
"outputs": ["dist/**"],
"dependsOn": ["@zitadel/proto#generate"]
}
}
}

View File

@@ -3,7 +3,7 @@
"tasks": {
"generate": {
"outputs": ["zitadel/**"],
"cache": false
"cache": true
}
}
}

41
pnpm-lock.yaml generated
View File

@@ -14,24 +14,6 @@ importers:
'@changesets/cli':
specifier: ^2.29.2
version: 2.29.2
'@faker-js/faker':
specifier: ^9.7.0
version: 9.7.0
'@otplib/core':
specifier: ^12.0.0
version: 12.0.1
'@otplib/plugin-crypto':
specifier: ^12.0.0
version: 12.0.1
'@otplib/plugin-thirty-two':
specifier: ^12.0.0
version: 12.0.1
'@playwright/test':
specifier: ^1.52.0
version: 1.52.0
'@types/node':
specifier: ^22.14.1
version: 22.14.1
'@vitejs/plugin-react':
specifier: ^4.4.1
version: 4.4.1(vite@6.3.2(@types/node@22.14.1)(jiti@1.21.6)(sass@1.87.0)(yaml@2.7.1))
@@ -220,7 +202,28 @@ importers:
specifier: ^5.8.3
version: 5.8.3
apps/login-integration-testsuite:
apps/login-test-acceptance:
devDependencies:
'@faker-js/faker':
specifier: ^9.7.0
version: 9.7.0
'@otplib/core':
specifier: ^12.0.0
version: 12.0.1
'@otplib/plugin-crypto':
specifier: ^12.0.0
version: 12.0.1
'@otplib/plugin-thirty-two':
specifier: ^12.0.0
version: 12.0.1
'@playwright/test':
specifier: ^1.52.0
version: 1.52.0
typescript:
specifier: ^5.8.3
version: 5.8.3
apps/login-test-integration:
devDependencies:
'@types/node':
specifier: ^22.14.1

View File

@@ -25,6 +25,7 @@
"start": {},
"start:built": {},
"test:unit": {},
"test:unit:standalone": {},
"test:integration": {},
"test:integration:run": {},
"test:watch": {