create-m5kdev 0.38.1 → 0.38.3

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,6 +1,6 @@
1
1
  {
2
2
  "name": "create-m5kdev",
3
- "version": "0.38.1",
3
+ "version": "0.38.3",
4
4
  "license": "GPL-3.0-only",
5
5
  "engines": {
6
6
  "node": ">=24"
@@ -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 invitedRow.getByRole("button", { name: `Role for ${invitee}` }).click();
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
- const nameField = invitedRow.getByRole("textbox", { name: `Name for ${invitee}` });
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("textbox", { name: "Name for Kitchen lead" })).toHaveValue(
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 invitedRow.getByRole("button", { name: `Role for ${invitee}` }).click();
366
- await page.getByRole("option", { name: /^Admin$/ }).click();
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.1
11
- "@m5kdev/commons": 0.38.1
12
- "@m5kdev/config": 0.38.1
13
- "@m5kdev/email": 0.38.1
14
- "@m5kdev/expo": 0.38.1
15
- "@m5kdev/frontend": 0.38.1
16
- "@m5kdev/module-clay": 0.38.1
17
- "@m5kdev/module-docx": 0.38.1
18
- "@m5kdev/module-pdf": 0.38.1
19
- "@m5kdev/module-social": 0.38.1
20
- "@m5kdev/module-video": 0.38.1
21
- "@m5kdev/web-ui": 0.38.1
10
+ "@m5kdev/backend": 0.38.3
11
+ "@m5kdev/commons": 0.38.3
12
+ "@m5kdev/config": 0.38.3
13
+ "@m5kdev/email": 0.38.3
14
+ "@m5kdev/expo": 0.38.3
15
+ "@m5kdev/frontend": 0.38.3
16
+ "@m5kdev/module-clay": 0.38.3
17
+ "@m5kdev/module-docx": 0.38.3
18
+ "@m5kdev/module-pdf": 0.38.3
19
+ "@m5kdev/module-social": 0.38.3
20
+ "@m5kdev/module-video": 0.38.3
21
+ "@m5kdev/web-ui": 0.38.3
22
22
  "@mastra/core": 1.51.0
23
23
  "@openrouter/ai-sdk-provider": 3.0.0
24
24
  "@opentelemetry/api": 1.9.0