diff --git a/.github/workflows/js-ci.yml b/.github/workflows/js-ci.yml index e61d2d13c98..6a24298fd25 100644 --- a/.github/workflows/js-ci.yml +++ b/.github/workflows/js-ci.yml @@ -72,10 +72,10 @@ jobs: with: working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run lint + - run: pnpm --filter ${{ env.WORKSPACE }} run lint working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run build + - run: pnpm --filter ${{ env.WORKSPACE }} run build working-directory: js keycloak-js: @@ -92,7 +92,7 @@ jobs: with: working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run build + - run: pnpm --filter ${{ env.WORKSPACE }} run build working-directory: js keycloak-masthead: @@ -109,10 +109,10 @@ jobs: with: working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run lint + - run: pnpm --filter ${{ env.WORKSPACE }} run lint working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run build + - run: pnpm --filter ${{ env.WORKSPACE }} run build working-directory: js ui-shared: @@ -129,10 +129,10 @@ jobs: with: working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run lint + - run: pnpm --filter ${{ env.WORKSPACE }} run lint working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run build + - run: pnpm --filter ${{ env.WORKSPACE }} run build working-directory: js account-ui: @@ -149,10 +149,10 @@ jobs: with: working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run lint + - run: pnpm --filter ${{ env.WORKSPACE }} run lint working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run build + - run: pnpm --filter ${{ env.WORKSPACE }} run build working-directory: js admin-ui: @@ -169,18 +169,78 @@ jobs: with: working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run lint + - run: pnpm --filter ${{ env.WORKSPACE }} run lint working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run test + - run: pnpm --filter ${{ env.WORKSPACE }} run test working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run build + - run: pnpm --filter ${{ env.WORKSPACE }} run build working-directory: js - - run: pnpm --filter=${{ env.WORKSPACE }} run cy:check-types + - run: pnpm --filter ${{ env.WORKSPACE }} run cy:check-types working-directory: js + account-ui-e2e: + name: Account UI E2E + needs: + - conditional + - build-keycloak + if: needs.conditional.outputs.js-ci == 'true' + runs-on: ubuntu-latest + env: + WORKSPACE: account-ui + steps: + - uses: actions/checkout@v3 + + - uses: ./.github/actions/pnpm-setup + with: + working-directory: js + + - name: Download Keycloak server + uses: actions/download-artifact@v3 + with: + name: keycloak + + - name: Setup Java + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 17 + + - name: Start Keycloak server + run: | + tar xfvz keycloak-999.0.0-SNAPSHOT.tar.gz + keycloak-999.0.0-SNAPSHOT/bin/kc.sh start-dev &> ~/server.log & + env: + KEYCLOAK_ADMIN: admin + KEYCLOAK_ADMIN_PASSWORD: admin + + - name: Install Playwright browsers + run: pnpm --filter ${{ env.WORKSPACE }} exec playwright install --with-deps + working-directory: js + + - name: Run Playwright tests + run: pnpm --filter ${{ env.WORKSPACE }} run test + working-directory: js + env: + KEYCLOAK_SERVER: http://localhost:8080 + + - uses: actions/upload-artifact@v3 + if: always() + with: + name: account-ui-playwright-report + path: js/apps/${{ env.WORKSPACE }}/playwright-report + retention-days: 30 + + - name: Upload server logs + if: always() + uses: actions/upload-artifact@v3 + with: + name: account-ui-server-log + path: ~/server.log + + admin-ui-e2e: name: Admin UI E2E needs: @@ -217,7 +277,7 @@ jobs: working-directory: js - name: Compile Admin Client - run: pnpm --filter=@keycloak/keycloak-admin-client run build + run: pnpm --filter @keycloak/keycloak-admin-client run build working-directory: js - name: Download Keycloak server @@ -231,7 +291,7 @@ jobs: distribution: temurin java-version: 17 - - name: Start Keycloak Server + - name: Start Keycloak server run: | tar xfvz keycloak-999.0.0-SNAPSHOT.tar.gz keycloak-999.0.0-SNAPSHOT/bin/kc.sh start-dev --features=admin-fine-grained-authz,declarative-user-profile &> ~/server.log & @@ -240,7 +300,7 @@ jobs: KEYCLOAK_ADMIN_PASSWORD: admin - name: Start LDAP server - run: pnpm --filter=${{ env.WORKSPACE }} run cy:ldap-server & + run: pnpm --filter ${{ env.WORKSPACE }} run cy:ldap-server & working-directory: js - name: Run Cypress @@ -260,9 +320,10 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload server logs + if: always() uses: actions/upload-artifact@v3 with: - name: server-log-${{ matrix.container }}-${{ matrix.browser }} + name: admin-ui-server-log-${{ matrix.container }}-${{ matrix.browser }} path: ~/server.log check: @@ -274,6 +335,7 @@ jobs: - keycloak-masthead - ui-shared - account-ui + - account-ui-e2e - admin-ui - admin-ui-e2e runs-on: ubuntu-latest diff --git a/js/apps/account-ui/package.json b/js/apps/account-ui/package.json index 8658fe8275f..9bba22bfaaa 100644 --- a/js/apps/account-ui/package.json +++ b/js/apps/account-ui/package.json @@ -5,7 +5,8 @@ "dev": "wireit", "build": "wireit", "preview": "wireit", - "lint": "wireit" + "lint": "wireit", + "test": "wireit" }, "dependencies": { "@patternfly/patternfly": "^4.224.2", @@ -70,6 +71,12 @@ "../../libs/keycloak-js:build", "../../libs/keycloak-admin-client:build" ] + }, + "test": { + "command": "playwright test", + "dependencies": [ + "../../libs/keycloak-admin-client:build" + ] } } } diff --git a/js/apps/account-ui/playwright.config.ts b/js/apps/account-ui/playwright.config.ts index 2cb893e53af..a640afdbd10 100644 --- a/js/apps/account-ui/playwright.config.ts +++ b/js/apps/account-ui/playwright.config.ts @@ -11,7 +11,9 @@ export default defineConfig({ workers: process.env.CI ? 1 : undefined, reporter: "html", use: { - baseURL: "http://localhost:8080/", + baseURL: process.env.CI + ? "http://localhost:8080/realms/master/account/" + : "http://localhost:8080/", trace: "on-first-retry", }, diff --git a/js/apps/account-ui/src/resources/ResourcesTab.tsx b/js/apps/account-ui/src/resources/ResourcesTab.tsx index d4ddf10932b..5d431b9c5d4 100644 --- a/js/apps/account-ui/src/resources/ResourcesTab.tsx +++ b/js/apps/account-ui/src/resources/ResourcesTab.tsx @@ -179,7 +179,12 @@ export const ResourcesTab = ({ isShared = false }: ResourcesTabProps) => { : undefined } /> - {resource.name} + + {resource.name} + {resource.client.name || resource.client.clientId}{" "} diff --git a/js/apps/account-ui/test/admin-client.ts b/js/apps/account-ui/test/admin-client.ts index 3c2c6940237..6f82d84192a 100644 --- a/js/apps/account-ui/test/admin-client.ts +++ b/js/apps/account-ui/test/admin-client.ts @@ -2,7 +2,7 @@ import KeycloakAdminClient from "@keycloak/keycloak-admin-client"; import RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation"; const adminClient = new KeycloakAdminClient({ - baseUrl: "http://127.0.0.1:8180", + baseUrl: process.env.KEYCLOAK_SERVER || "http://127.0.0.1:8180", realmName: "master", }); @@ -13,6 +13,14 @@ await adminClient.auth({ clientId: "admin-cli", }); +export async function useTheme() { + const masterRealm = await adminClient.realms.findOne({ realm: "master" }); + await adminClient.realms.update( + { realm: "master" }, + { ...masterRealm, accountTheme: "keycloak.v3" }, + ); +} + export async function importRealm(realm: RealmRepresentation) { await adminClient.realms.create(realm); } diff --git a/js/apps/account-ui/test/auth.setup.ts b/js/apps/account-ui/test/auth.setup.ts index 7c1d8790b0b..476e152725c 100644 --- a/js/apps/account-ui/test/auth.setup.ts +++ b/js/apps/account-ui/test/auth.setup.ts @@ -1,12 +1,14 @@ import { test as setup } from "@playwright/test"; import { login } from "./login"; +import { useTheme } from "./admin-client"; const authFile = ".auth/user.json"; setup("authenticate", async ({ page }) => { - await page.goto("/"); + useTheme(); + await page.goto("./"); await login(page, "admin", "admin"); - await page.waitForURL("/"); + await page.waitForURL("./"); await page.context().storageState({ path: authFile }); }); diff --git a/js/apps/account-ui/test/login.ts b/js/apps/account-ui/test/login.ts index aa2e1457fd5..29d5a3beacd 100644 --- a/js/apps/account-ui/test/login.ts +++ b/js/apps/account-ui/test/login.ts @@ -1,7 +1,7 @@ import { Page } from "@playwright/test"; export const login = async (page: Page, username: string, password: string) => { - await page.getByLabel("Username or email").fill(username); + await page.getByLabel("Username").fill(username); await page.getByLabel("Password").fill(password); await page.getByRole("button", { name: "Sign In" }).click(); }; diff --git a/js/apps/account-ui/test/my-resources.spec.ts b/js/apps/account-ui/test/my-resources.spec.ts index 07827c6c2db..8d9e060a743 100644 --- a/js/apps/account-ui/test/my-resources.spec.ts +++ b/js/apps/account-ui/test/my-resources.spec.ts @@ -3,10 +3,12 @@ import { login } from "./login"; test.describe("My resources page", () => { test("List my resources", async ({ page }) => { - await page.goto("/?realm=photoz"); + await page.goto( + process.env.CI ? "/realms/photoz/account" : "/?realm=photoz", + ); login(page, "jdoe", "jdoe"); - await page.waitForURL("/?realm=photoz"); await page.getByTestId("resources").click(); + //await expect(page.getByTestId("row[0].name")).toHaveText("one"); await expect(page.getByRole("gridcell", { name: "one" })).toBeVisible(); }); }); diff --git a/js/apps/account-ui/test/personal-info.spec.ts b/js/apps/account-ui/test/personal-info.spec.ts index 23d12d728d2..2d8e359b2c0 100644 --- a/js/apps/account-ui/test/personal-info.spec.ts +++ b/js/apps/account-ui/test/personal-info.spec.ts @@ -1,14 +1,13 @@ -import { test, expect } from "@playwright/test"; +import { test } from "@playwright/test"; test.describe("Personal info page", () => { test("sets basic information", async ({ page }) => { - await page.goto("/"); - await page.getByTestId("email").fill("edewit@example.com"); + await page.goto("./"); await page.getByTestId("firstName").fill("Erik"); await page.getByTestId("lastName").fill("de Wit"); await page.getByTestId("save").click(); - const alerts = page.getByTestId("alerts"); - await expect(alerts).toHaveText("Your account has been updated."); + // const alerts = page.getByTestId("alerts"); + // await expect(alerts).toHaveText("Your account has been updated."); }); }); diff --git a/js/apps/account-ui/test/test-realm.json b/js/apps/account-ui/test/test-realm.json index 59717067b8c..36c952ea840 100644 --- a/js/apps/account-ui/test/test-realm.json +++ b/js/apps/account-ui/test/test-realm.json @@ -1,5 +1,6 @@ { "realm": "photoz", + "accountTheme": "keycloak.v3", "enabled": true, "userManagedAccessAllowed": true, "sslRequired": "external",