Use correct PNPM workspace names on CI (#29973)
Closes #29976 Signed-off-by: Jon Koops <jonkoops@gmail.com> Signed-off-by: Hynek Mlnarik <hmlnarik@redhat.com> Co-authored-by: Hynek Mlnarik <hmlnarik@redhat.com>
This commit is contained in:
parent
4c39fcc79d
commit
c17023270c
10 changed files with 60 additions and 72 deletions
58
.github/workflows/js-ci.yml
vendored
58
.github/workflows/js-ci.yml
vendored
|
@ -74,9 +74,9 @@ jobs:
|
||||||
|
|
||||||
- uses: ./.github/actions/pnpm-setup
|
- uses: ./.github/actions/pnpm-setup
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} lint
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} lint
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} build
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} build
|
||||||
|
|
||||||
keycloak-js:
|
keycloak-js:
|
||||||
name: Keycloak JS
|
name: Keycloak JS
|
||||||
|
@ -90,23 +90,7 @@ jobs:
|
||||||
|
|
||||||
- uses: ./.github/actions/pnpm-setup
|
- uses: ./.github/actions/pnpm-setup
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} build
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} build
|
||||||
|
|
||||||
keycloak-masthead:
|
|
||||||
name: Keycloak Masthead
|
|
||||||
needs: conditional
|
|
||||||
if: needs.conditional.outputs.js-ci == 'true'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
WORKSPACE: keycloak-masthead
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: ./.github/actions/pnpm-setup
|
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} lint
|
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} build
|
|
||||||
|
|
||||||
ui-shared:
|
ui-shared:
|
||||||
name: UI Shared
|
name: UI Shared
|
||||||
|
@ -114,15 +98,15 @@ jobs:
|
||||||
if: needs.conditional.outputs.js-ci == 'true'
|
if: needs.conditional.outputs.js-ci == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
WORKSPACE: ui-shared
|
WORKSPACE: "@keycloak/keycloak-ui-shared"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: ./.github/actions/pnpm-setup
|
- uses: ./.github/actions/pnpm-setup
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} lint
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} lint
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} build
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} build
|
||||||
|
|
||||||
account-ui:
|
account-ui:
|
||||||
name: Account UI
|
name: Account UI
|
||||||
|
@ -130,15 +114,15 @@ jobs:
|
||||||
if: needs.conditional.outputs.js-ci == 'true'
|
if: needs.conditional.outputs.js-ci == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
WORKSPACE: account-ui
|
WORKSPACE: "@keycloak/keycloak-account-ui"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: ./.github/actions/pnpm-setup
|
- uses: ./.github/actions/pnpm-setup
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} lint
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} lint
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} build
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} build
|
||||||
|
|
||||||
admin-ui:
|
admin-ui:
|
||||||
name: Admin UI
|
name: Admin UI
|
||||||
|
@ -152,13 +136,13 @@ jobs:
|
||||||
|
|
||||||
- uses: ./.github/actions/pnpm-setup
|
- uses: ./.github/actions/pnpm-setup
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} lint
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} lint
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} test
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} test
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} build
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} build
|
||||||
|
|
||||||
- run: pnpm --filter ${{ env.WORKSPACE }} cy:check-types
|
- run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} cy:check-types
|
||||||
|
|
||||||
account-ui-e2e:
|
account-ui-e2e:
|
||||||
name: Account UI E2E
|
name: Account UI E2E
|
||||||
|
@ -168,7 +152,7 @@ jobs:
|
||||||
if: needs.conditional.outputs.js-ci == 'true'
|
if: needs.conditional.outputs.js-ci == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
WORKSPACE: account-ui
|
WORKSPACE: "@keycloak/keycloak-account-ui"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
@ -194,18 +178,19 @@ jobs:
|
||||||
KEYCLOAK_ADMIN_PASSWORD: admin
|
KEYCLOAK_ADMIN_PASSWORD: admin
|
||||||
|
|
||||||
- name: Install Playwright browsers
|
- name: Install Playwright browsers
|
||||||
run: pnpm --filter ${{ env.WORKSPACE }} exec playwright install --with-deps
|
run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} exec playwright install --with-deps
|
||||||
|
|
||||||
- name: Run Playwright tests
|
- name: Run Playwright tests
|
||||||
run: pnpm --filter ${{ env.WORKSPACE }} test
|
run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} test
|
||||||
env:
|
env:
|
||||||
KEYCLOAK_SERVER: http://localhost:8080
|
KEYCLOAK_SERVER: http://localhost:8080
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- name: Upload Playwright report
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: account-ui-playwright-report
|
name: account-ui-playwright-report
|
||||||
path: js/apps/${{ env.WORKSPACE }}/playwright-report
|
path: js/apps/account-ui/playwright-report
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Upload server logs
|
- name: Upload server logs
|
||||||
|
@ -267,7 +252,7 @@ jobs:
|
||||||
- uses: ./.github/actions/pnpm-setup
|
- uses: ./.github/actions/pnpm-setup
|
||||||
|
|
||||||
- name: Compile Admin Client
|
- name: Compile Admin Client
|
||||||
run: pnpm --filter @keycloak/keycloak-admin-client build
|
run: pnpm --fail-if-no-match --filter @keycloak/keycloak-admin-client build
|
||||||
|
|
||||||
- name: Download Keycloak server
|
- name: Download Keycloak server
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
|
@ -289,7 +274,7 @@ jobs:
|
||||||
KEYCLOAK_ADMIN_PASSWORD: admin
|
KEYCLOAK_ADMIN_PASSWORD: admin
|
||||||
|
|
||||||
- name: Start LDAP server
|
- name: Start LDAP server
|
||||||
run: pnpm --filter ${{ env.WORKSPACE }} cy:ldap-server &
|
run: pnpm --fail-if-no-match --filter ${{ env.WORKSPACE }} cy:ldap-server &
|
||||||
|
|
||||||
- name: Run Cypress
|
- name: Run Cypress
|
||||||
uses: cypress-io/github-action@v6
|
uses: cypress-io/github-action@v6
|
||||||
|
@ -329,7 +314,6 @@ jobs:
|
||||||
- build-keycloak
|
- build-keycloak
|
||||||
- admin-client
|
- admin-client
|
||||||
- keycloak-js
|
- keycloak-js
|
||||||
- keycloak-masthead
|
|
||||||
- ui-shared
|
- ui-shared
|
||||||
- account-ui
|
- account-ui
|
||||||
- account-ui-e2e
|
- account-ui-e2e
|
||||||
|
|
|
@ -11,6 +11,10 @@ export default defineConfig({
|
||||||
retries: process.env.CI ? 2 : 0,
|
retries: process.env.CI ? 2 : 0,
|
||||||
workers: 1,
|
workers: 1,
|
||||||
reporter: process.env.CI ? [["github"], ["html"]] : "list",
|
reporter: process.env.CI ? [["github"], ["html"]] : "list",
|
||||||
|
expect: {
|
||||||
|
timeout: 20 * 1000,
|
||||||
|
},
|
||||||
|
|
||||||
use: {
|
use: {
|
||||||
baseURL: `http://localhost:8080${getRootPath()}`,
|
baseURL: `http://localhost:8080${getRootPath()}`,
|
||||||
trace: "on-first-retry",
|
trace: "on-first-retry",
|
||||||
|
@ -31,6 +35,7 @@ export default defineConfig({
|
||||||
name: "chromium",
|
name: "chromium",
|
||||||
use: {
|
use: {
|
||||||
...devices["Desktop Chrome"],
|
...devices["Desktop Chrome"],
|
||||||
|
viewport: { width: 1920, height: 1200 },
|
||||||
},
|
},
|
||||||
dependencies: ["import realms"],
|
dependencies: ["import realms"],
|
||||||
},
|
},
|
||||||
|
|
|
@ -192,7 +192,11 @@ export const ShareTheResource = ({
|
||||||
)}
|
)}
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormProvider {...form}>
|
<FormProvider {...form}>
|
||||||
<FormGroup label="" fieldId="permissions-selected">
|
<FormGroup
|
||||||
|
label=""
|
||||||
|
fieldId="permissions-selected"
|
||||||
|
data-testid="permissions"
|
||||||
|
>
|
||||||
<SelectControl
|
<SelectControl
|
||||||
name="permissions"
|
name="permissions"
|
||||||
variant="typeaheadMulti"
|
variant="typeaheadMulti"
|
||||||
|
|
|
@ -9,7 +9,7 @@ test("Check page heading", async ({ page }) => {
|
||||||
"account-security/linked-accounts",
|
"account-security/linked-accounts",
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(linkedAccountsNavItem).toBeVisible();
|
await expect(linkedAccountsNavItem).toBeVisible();
|
||||||
await linkedAccountsNavItem.click();
|
await linkedAccountsNavItem.click();
|
||||||
await expect(page.getByTestId("page-heading")).toHaveText("Linked accounts");
|
await expect(page.getByTestId("page-heading")).toHaveText("Linked accounts");
|
||||||
});
|
});
|
||||||
|
|
|
@ -70,6 +70,7 @@ test.describe("Applications test", () => {
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
await expect(page).toHaveURL(getAdminUrl());
|
await expect(page).toHaveURL(getAdminUrl());
|
||||||
await page.waitForURL(getAdminUrl());
|
await page.waitForURL(getAdminUrl());
|
||||||
|
await expect(page.getByTestId("realmSelector")).toBeVisible();
|
||||||
|
|
||||||
await page.goto(getRootPath());
|
await page.goto(getRootPath());
|
||||||
await page.waitForURL(getAccountUrl());
|
await page.waitForURL(getAccountUrl());
|
||||||
|
|
|
@ -36,14 +36,20 @@ test.describe("My resources page", () => {
|
||||||
"Share with alice",
|
"Share with alice",
|
||||||
);
|
);
|
||||||
|
|
||||||
await page.getByRole("button", { name: "Options menu" }).click();
|
await page
|
||||||
|
.getByTestId("permissions")
|
||||||
|
.getByRole("button", { expanded: false })
|
||||||
|
.click();
|
||||||
await page.getByRole("option", { name: "album:view" }).click();
|
await page.getByRole("option", { name: "album:view" }).click();
|
||||||
await page.getByRole("button", { name: "Options menu" }).click();
|
await page
|
||||||
|
.getByTestId("permissions")
|
||||||
|
.getByRole("button", { expanded: true })
|
||||||
|
.click();
|
||||||
|
|
||||||
await page.getByTestId("done").click();
|
await page.getByTestId("done").click();
|
||||||
|
|
||||||
await page.getByTestId("expand-one").click();
|
await page.getByTestId("expand-one").click();
|
||||||
expect(page.getByTestId("shared-with-alice")).toBeDefined();
|
await expect(page.getByTestId("shared-with-alice")).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("One is shared with alice", async ({ page }) => {
|
test("One is shared with alice", async ({ page }) => {
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
import { expect, test } from "@playwright/test";
|
|
||||||
import { login } from "../login";
|
|
||||||
|
|
||||||
test.describe("Verifiable Credentials page", () => {
|
|
||||||
test("Get offer for test-credential.", async ({ page }) => {
|
|
||||||
await login(page, "test-user", "test");
|
|
||||||
await expect(page.getByTestId("qr-code")).toBeHidden();
|
|
||||||
await page.getByTestId("oid4vci").click();
|
|
||||||
await page.getByTestId("credential-select").click();
|
|
||||||
await expect(
|
|
||||||
page.getByTestId("select-verifiable-credential"),
|
|
||||||
).toBeVisible();
|
|
||||||
await expect(page.getByTestId("select-natural-person")).toBeVisible();
|
|
||||||
await page.getByTestId("select-natural-person").click();
|
|
||||||
await expect(page.getByTestId("qr-code")).toBeVisible();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -30,7 +30,7 @@ test.describe("Personal info page", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe("Personal info with userprofile enabled", async () => {
|
test.describe("Personal info with userprofile enabled", () => {
|
||||||
let user: string;
|
let user: string;
|
||||||
test.beforeAll(async () => {
|
test.beforeAll(async () => {
|
||||||
await importUserProfile(userProfileConfig as UserProfileConfig, realm);
|
await importUserProfile(userProfileConfig as UserProfileConfig, realm);
|
||||||
|
@ -54,9 +54,9 @@ test.describe("Personal info with userprofile enabled", async () => {
|
||||||
|
|
||||||
await expect(page.locator("#select")).toBeVisible();
|
await expect(page.locator("#select")).toBeVisible();
|
||||||
await expect(page.getByTestId("help-label-select")).toBeVisible();
|
await expect(page.getByTestId("help-label-select")).toBeVisible();
|
||||||
expect(page.getByText("Alternative email")).toHaveCount(1);
|
await expect(page.getByText("Alternative email")).toHaveCount(1);
|
||||||
expect(page.getByPlaceholder("Deutsch")).toHaveCount(1);
|
await expect(page.getByPlaceholder("Deutsch")).toHaveCount(1);
|
||||||
page.getByTestId("help-label-email2").click();
|
await page.getByTestId("help-label-email2").click();
|
||||||
await expect(page.getByText("Español")).toHaveCount(1);
|
await expect(page.getByText("Español")).toHaveCount(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -66,11 +66,12 @@ test.describe("Personal info with userprofile enabled", async () => {
|
||||||
await page.getByText("Alternate Language").click();
|
await page.getByText("Alternate Language").click();
|
||||||
await page.waitForSelector("text=Italiano");
|
await page.waitForSelector("text=Italiano");
|
||||||
|
|
||||||
|
await page.getByText("Alternate Language").click();
|
||||||
await page.locator("*:focus").press("Control+A");
|
await page.locator("*:focus").press("Control+A");
|
||||||
await page.locator("*:focus").pressSequentially("S");
|
await page.locator("*:focus").pressSequentially("S");
|
||||||
await expect(page.getByText("Italiano")).toHaveCount(0);
|
await expect(page.getByText("Italiano")).toHaveCount(0);
|
||||||
expect(page.getByText("Suomi")).toBeVisible();
|
await expect(page.getByText("Slovak")).toBeVisible();
|
||||||
expect(page.getByText('Create "S"')).not.toBeVisible();
|
await expect(page.getByText('Create "S"')).toBeHidden();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("render long list of locales as typeahead", async ({ page }) => {
|
test("render long list of locales as typeahead", async ({ page }) => {
|
||||||
|
@ -79,11 +80,12 @@ test.describe("Personal info with userprofile enabled", async () => {
|
||||||
await page.locator("#locale").click();
|
await page.locator("#locale").click();
|
||||||
await page.waitForSelector("text=Italiano");
|
await page.waitForSelector("text=Italiano");
|
||||||
|
|
||||||
|
await page.locator("#locale").click();
|
||||||
await page.locator("*:focus").press("Control+A");
|
await page.locator("*:focus").press("Control+A");
|
||||||
await page.locator("*:focus").pressSequentially("S");
|
await page.locator("*:focus").pressSequentially("S");
|
||||||
await expect(page.getByText("Italiano")).toHaveCount(0);
|
await expect(page.getByText("Italiano")).toHaveCount(0);
|
||||||
expect(page.getByText("Suomi")).toBeVisible();
|
await expect(page.getByText("Slovak")).toBeVisible();
|
||||||
expect(page.getByText('Create "S"')).not.toBeVisible();
|
await expect(page.getByText('Create "S"')).toBeHidden();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("save user profile", async ({ page }) => {
|
test("save user profile", async ({ page }) => {
|
||||||
|
@ -112,7 +114,7 @@ test.describe("Personal info with userprofile enabled", async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// skip currently the locale is not part of the response
|
// skip currently the locale is not part of the response
|
||||||
test.describe.skip("Realm localization", async () => {
|
test.describe.skip("Realm localization", () => {
|
||||||
test.beforeAll(() => enableLocalization());
|
test.beforeAll(() => enableLocalization());
|
||||||
|
|
||||||
test("change locale", async ({ page }) => {
|
test("change locale", async ({ page }) => {
|
||||||
|
|
|
@ -3,9 +3,12 @@ import { test as setup } from "@playwright/test";
|
||||||
|
|
||||||
import { importRealm } from "./admin-client";
|
import { importRealm } from "./admin-client";
|
||||||
import groupsRealm from "./realms/groups-realm.json" assert { type: "json" };
|
import groupsRealm from "./realms/groups-realm.json" assert { type: "json" };
|
||||||
import resourcesRealm from "./realms/resources-realm.json" assert { type: "json" };
|
import resourcesRealm from "./realms/resources-realm.json" assert { type:
|
||||||
import userProfileRealm from "./realms/user-profile-realm.json" assert { type: "json" };
|
"json" };
|
||||||
import verifiableCredentialsRealm from "./realms/verifiable-credentials-realm.json" assert { type: "json" };
|
import userProfileRealm from "./realms/user-profile-realm.json" assert { type:
|
||||||
|
"json" };
|
||||||
|
import verifiableCredentialsRealm from "./realms/verifiable-credentials-realm.json" assert { type:
|
||||||
|
"json" };
|
||||||
|
|
||||||
setup("import realm", async () => {
|
setup("import realm", async () => {
|
||||||
await importRealm(groupsRealm as RealmRepresentation);
|
await importRealm(groupsRealm as RealmRepresentation);
|
||||||
|
|
|
@ -40,7 +40,7 @@ async function startServer() {
|
||||||
[
|
[
|
||||||
"start-dev",
|
"start-dev",
|
||||||
"--http-port=8180",
|
"--http-port=8180",
|
||||||
`--features="login2,account3,admin-fine-grained-authz,transient-users"`,
|
`--features="login2,account3,admin-fine-grained-authz,transient-users,oid4vc-vci"`,
|
||||||
...keycloakArgs,
|
...keycloakArgs,
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue