create-m5kdev 0.38.2 → 0.38.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type APIRequestContext, expect, type Page, test } from "@playwright/test";
|
|
1
|
+
import { type APIRequestContext, expect, type Locator, type Page, test } from "@playwright/test";
|
|
2
2
|
import {
|
|
3
3
|
authFetch,
|
|
4
4
|
clearEmails,
|
|
@@ -50,6 +50,44 @@ async function inviteFromMembersPage(page: Page, email: string) {
|
|
|
50
50
|
return invitedRow;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
async function saveMemberEdit(page: Page, row: Locator, changes: { name?: string; role?: string }) {
|
|
54
|
+
await row.getByRole("button", { name: /^edit member$/i }).click();
|
|
55
|
+
const dialog = page.getByRole("dialog");
|
|
56
|
+
await expect(dialog.getByRole("heading", { name: /^edit member$/i })).toBeVisible();
|
|
57
|
+
if (changes.name !== undefined) {
|
|
58
|
+
await dialog.getByLabel(/^name$/i).fill(changes.name);
|
|
59
|
+
}
|
|
60
|
+
if (changes.role !== undefined) {
|
|
61
|
+
await dialog.getByRole("button", { name: /^role$/i }).click();
|
|
62
|
+
await page.getByRole("option", { name: new RegExp(`^${changes.role}$`) }).click();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const mutationNames = [
|
|
66
|
+
...(changes.name !== undefined ? ["updateMemberName"] : []),
|
|
67
|
+
...(changes.role !== undefined ? ["updateMemberRole"] : []),
|
|
68
|
+
];
|
|
69
|
+
const responsePromise =
|
|
70
|
+
mutationNames.length === 0
|
|
71
|
+
? Promise.resolve(null)
|
|
72
|
+
: page.waitForResponse(
|
|
73
|
+
(response) =>
|
|
74
|
+
response.request().method() === "POST" &&
|
|
75
|
+
mutationNames.some((name) => response.url().includes(name))
|
|
76
|
+
);
|
|
77
|
+
await dialog.getByRole("button", { name: /^save$/i }).click();
|
|
78
|
+
if (mutationNames.length > 0) {
|
|
79
|
+
const response = await responsePromise;
|
|
80
|
+
expect(response).not.toBeNull();
|
|
81
|
+
if (response) {
|
|
82
|
+
expect(
|
|
83
|
+
response.ok(),
|
|
84
|
+
`${response.status()} ${response.statusText()}: ${await response.text()}`
|
|
85
|
+
).toBe(true);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
await expect(dialog).toBeHidden();
|
|
89
|
+
}
|
|
90
|
+
|
|
53
91
|
async function listOrganizationMembers(page: Page) {
|
|
54
92
|
const trpc = await createTrpcClient(page, profile);
|
|
55
93
|
return trpc.auth.listOrganizationMembers.query();
|
|
@@ -273,17 +311,7 @@ test("organization members page changes an invited member role before they accep
|
|
|
273
311
|
expect(invitedMemberId).toBeTruthy();
|
|
274
312
|
|
|
275
313
|
const invitedRow = page.getByRole("row").filter({ hasText: invitee });
|
|
276
|
-
await
|
|
277
|
-
const roleResponsePromise = page.waitForResponse(
|
|
278
|
-
(response) =>
|
|
279
|
-
response.request().method() === "POST" && response.url().includes("updateMemberRole")
|
|
280
|
-
);
|
|
281
|
-
await page.getByRole("option", { name: /^Admin$/ }).click();
|
|
282
|
-
const roleResponse = await roleResponsePromise;
|
|
283
|
-
expect(
|
|
284
|
-
roleResponse.ok(),
|
|
285
|
-
`${roleResponse.status()} ${roleResponse.statusText()}: ${await roleResponse.text()}`
|
|
286
|
-
).toBe(true);
|
|
314
|
+
await saveMemberEdit(page, invitedRow, { role: "Admin" });
|
|
287
315
|
|
|
288
316
|
const afterRole = findMemberByEmail(await listOrganizationMembers(page), invitee);
|
|
289
317
|
expect(afterRole?.id).toBe(invitedMemberId);
|
|
@@ -323,26 +351,13 @@ test("organization members page lets an admin edit a member name", async ({ page
|
|
|
323
351
|
expect(invited?.name).toBe(invitee);
|
|
324
352
|
|
|
325
353
|
const invitedRow = page.getByRole("row").filter({ hasText: invitee });
|
|
326
|
-
|
|
327
|
-
await nameField.fill("Kitchen lead");
|
|
328
|
-
const nameResponsePromise = page.waitForResponse(
|
|
329
|
-
(response) =>
|
|
330
|
-
response.request().method() === "POST" && response.url().includes("updateMemberName")
|
|
331
|
-
);
|
|
332
|
-
await nameField.blur();
|
|
333
|
-
const nameResponse = await nameResponsePromise;
|
|
334
|
-
expect(
|
|
335
|
-
nameResponse.ok(),
|
|
336
|
-
`${nameResponse.status()} ${nameResponse.statusText()}: ${await nameResponse.text()}`
|
|
337
|
-
).toBe(true);
|
|
354
|
+
await saveMemberEdit(page, invitedRow, { name: "Kitchen lead" });
|
|
338
355
|
|
|
339
356
|
const afterName = findMemberByEmail(await listOrganizationMembers(page), invitee);
|
|
340
357
|
expect(afterName?.id).toBe(invitedMemberId);
|
|
341
358
|
expect(afterName?.name).toBe("Kitchen lead");
|
|
342
359
|
expect(afterName?.userId).toBeNull();
|
|
343
|
-
await expect(invitedRow.getByRole("
|
|
344
|
-
"Kitchen lead"
|
|
345
|
-
);
|
|
360
|
+
await expect(invitedRow.getByRole("cell").first()).toHaveText("Kitchen lead");
|
|
346
361
|
});
|
|
347
362
|
|
|
348
363
|
test("organization members page resends, updates, cancels, and revives an invited seat", async ({
|
|
@@ -362,9 +377,8 @@ test("organization members page resends, updates, cancels, and revives an invite
|
|
|
362
377
|
expect(resent?.userId).toBeNull();
|
|
363
378
|
|
|
364
379
|
const invitedRow = page.getByRole("row").filter({ hasText: invitee });
|
|
365
|
-
await
|
|
366
|
-
await page.
|
|
367
|
-
await expect(page.getByText(/member role updated/i)).toBeVisible();
|
|
380
|
+
await saveMemberEdit(page, invitedRow, { role: "Admin" });
|
|
381
|
+
await expect(page.getByText(/member updated/i)).toBeVisible();
|
|
368
382
|
await expect
|
|
369
383
|
.poll(async () => findMemberByEmail(await listOrganizationMembers(page), invitee)?.role)
|
|
370
384
|
.toBe("admin");
|
|
@@ -7,18 +7,18 @@ catalogs:
|
|
|
7
7
|
"@heroui/react": 3.0.3
|
|
8
8
|
"@heroui/styles": 3.0.3
|
|
9
9
|
"@libsql/client": 0.17.4
|
|
10
|
-
"@m5kdev/backend": 0.38.
|
|
11
|
-
"@m5kdev/commons": 0.38.
|
|
12
|
-
"@m5kdev/config": 0.38.
|
|
13
|
-
"@m5kdev/email": 0.38.
|
|
14
|
-
"@m5kdev/expo": 0.38.
|
|
15
|
-
"@m5kdev/frontend": 0.38.
|
|
16
|
-
"@m5kdev/module-clay": 0.38.
|
|
17
|
-
"@m5kdev/module-docx": 0.38.
|
|
18
|
-
"@m5kdev/module-pdf": 0.38.
|
|
19
|
-
"@m5kdev/module-social": 0.38.
|
|
20
|
-
"@m5kdev/module-video": 0.38.
|
|
21
|
-
"@m5kdev/web-ui": 0.38.
|
|
10
|
+
"@m5kdev/backend": 0.38.4
|
|
11
|
+
"@m5kdev/commons": 0.38.4
|
|
12
|
+
"@m5kdev/config": 0.38.4
|
|
13
|
+
"@m5kdev/email": 0.38.4
|
|
14
|
+
"@m5kdev/expo": 0.38.4
|
|
15
|
+
"@m5kdev/frontend": 0.38.4
|
|
16
|
+
"@m5kdev/module-clay": 0.38.4
|
|
17
|
+
"@m5kdev/module-docx": 0.38.4
|
|
18
|
+
"@m5kdev/module-pdf": 0.38.4
|
|
19
|
+
"@m5kdev/module-social": 0.38.4
|
|
20
|
+
"@m5kdev/module-video": 0.38.4
|
|
21
|
+
"@m5kdev/web-ui": 0.38.4
|
|
22
22
|
"@mastra/core": 1.51.0
|
|
23
23
|
"@openrouter/ai-sdk-provider": 3.0.0
|
|
24
24
|
"@opentelemetry/api": 1.9.0
|