Skip to content

Commit fbcd1ac

Browse files
committed
WIP
1 parent 52663d4 commit fbcd1ac

File tree

12 files changed

+1275
-539
lines changed

12 files changed

+1275
-539
lines changed

INSTRUCTIONS.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
## Test rewrite guidelines
2+
3+
## Refactor test one file at a time
4+
5+
Do not refactor all the test files at once, refactor one file, then run the tests until they are fully functional before moving on to the next file.
6+
7+
## Running the tests
8+
9+
You can run the the tests from a specific file using the following command:
10+
11+
```sh
12+
pnpm --filter @keycloak/keycloak-admin-ui test:integration -- clients/initial-access.spec.ts
13+
```
14+
15+
Change `clients/initial-access.spec.ts` to whatever spec file you want to run. You must be in the `js/` directory from the project root for this command to work.
16+
17+
## Use `createTestBed()` for each test
18+
19+
Use `createTestBed()` to set up the data for each test, most tests will not need any additional data, but any realm data that needs to be set up for the test can be passed in as the first parameter, e.g.:
20+
21+
```ts
22+
await using testBed = await createTestBed({
23+
groups: [{ name: "test-group" }],
24+
});
25+
```
26+
27+
There should be no shared global calls (e.g. in `beforeAll()`) to set up `createTestBed()`, each test must do so individually. If a lot of data is shared between tests.
28+
29+
If needed, use the admin client to make REST API calls, but only do so if it is not possible to provide the data to `createTestBed()`. In fact, if you see existing tests using the admin client, and it is possible to use `createTestBed()` with some data instead, then refactor that as well.
30+
31+
Note that often this data will be set up using UUIDs in their name to prevent collisions in existing tests, because `createTestBed()` already isolates everything on a realm level this UUID logic can be removed, using simple names that are unique to the test case instead.
32+
33+
## Navigate using `login()` or `navigateTo()`
34+
35+
After setting up a test's data using `createTestBed()`, it is common to call `login()` to log in, and navigate to the page you want to land on:
36+
37+
```ts
38+
await login(page, { to: toClients({ realm: testBed.realm }) });
39+
```
40+
41+
If you ever find the need to navigate somewhere else that is not immediately obvious from the UI, and is not the initial landing page after logging in, you can call `navigateTo()` (used by `login()` under the hood):
42+
43+
```ts
44+
await login(page, { to: toClient({ realm: testBed.realm, id: "my-client-id" }) });
45+
```
46+
47+
## Make all tests fully parallel (no `test.describe.serial()`!)
48+
49+
A key benefit of `createTestBed()` is that it allows each test to operate on an isolated realm. This ensures that the tests do not run into each others data. This is by design, to allow us to make use of full parallelization. Therefore, do not use `test.describe.serial()` in the final result, under no circumstances (unless you are debugging for whatever reason during development).
50+
51+
## Conventional test naming
52+
53+
Make sure the names of the tests are conventional (no 'should', or 'test'), write them as if you use a verb:
54+
55+
```ts
56+
test.describe("Groups overview", () => {
57+
test("removes an item from the list", () => {});
58+
});
59+
```
60+
61+
## Use adminClient when createTestBed() data isn't sufficient
62+
63+
When you need to create entities like clients and get their IDs for navigation, or when you need complex setup that can't be expressed through `createTestBed()`, use the `adminClient` directly in the test:
64+
65+
```ts
66+
await using testBed = await createTestBed();
67+
68+
const { id: clientId } = await adminClient.createClient({
69+
clientId: "test-client",
70+
publicClient: true,
71+
realm: testBed.realm,
72+
});
73+
74+
await login(page, {
75+
to: toClient({
76+
realm: testBed.realm,
77+
clientId: clientId!,
78+
tab: "advanced",
79+
}),
80+
});
81+
```
82+
83+
Note that navigation routes often require the internal ID (UUID), not the clientId string.
84+
85+
## Use existing tests as a reference
86+
87+
If you are ever in doubt on how to approach something, you can use existing tests that use `createTestBed()` as a reference.
88+
89+
## Update instructions when needed
90+
91+
Feel free to supplement this instructions file with findings you might deem relevant to rewriting tests, or if I provide feedback that might be generally applicable.
92+

js/apps/admin-ui/playwright.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default defineConfig({
1010
fullyParallel: true,
1111
// The admin console tests are not optimized for parallel execution, long-term
1212
// this should be addressed and 'workers' should be returned to the default value.
13-
workers: 1,
13+
// workers: 1,
1414
forbidOnly: !!process.env.CI,
1515
reporter: process.env.CI ? [["github"], ["html"]] : "list",
1616

0 commit comments

Comments
 (0)