@open-mercato/core 0.6.8-develop.6930.1.1e5976efc3 → 0.6.8-develop.6931.1.4a1e1c786b

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.
@@ -1,5 +1,6 @@
1
1
  import { expect } from "@playwright/test";
2
2
  const DEFAULT_UI_TIMEOUT_MS = 1e4;
3
+ const CONTROLLED_INPUT_SETTLE_MS = 400;
3
4
  async function fillControlledInput(input, value, timeoutMs = DEFAULT_UI_TIMEOUT_MS) {
4
5
  const deadline = Date.now() + timeoutMs;
5
6
  let lastError = null;
@@ -10,6 +11,8 @@ async function fillControlledInput(input, value, timeoutMs = DEFAULT_UI_TIMEOUT_
10
11
  await input.click({ timeout: 2e3 });
11
12
  await input.fill(value);
12
13
  await expect(input).toHaveValue(value, { timeout: 1500 });
14
+ await input.page().waitForTimeout(CONTROLLED_INPUT_SETTLE_MS);
15
+ await expect(input).toHaveValue(value, { timeout: 1500 });
13
16
  return;
14
17
  } catch (error) {
15
18
  lastError = error;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/helpers/integration/ui.ts"],
4
- "sourcesContent": ["import { expect, type Locator, type Page, type Response } from '@playwright/test'\n\nconst DEFAULT_UI_TIMEOUT_MS = 10_000\n\nexport async function fillControlledInput(\n input: Locator,\n value: string,\n timeoutMs = DEFAULT_UI_TIMEOUT_MS,\n): Promise<void> {\n const deadline = Date.now() + timeoutMs\n let lastError: unknown = null\n\n while (Date.now() < deadline) {\n try {\n await input.scrollIntoViewIfNeeded().catch(() => {})\n await input.click({ timeout: 2_000 })\n await input.fill(value)\n await expect(input).toHaveValue(value, { timeout: 1_500 })\n return\n } catch (error) {\n lastError = error\n await input.page().waitForTimeout(150)\n }\n }\n\n if (lastError instanceof Error) {\n throw lastError\n }\n throw new Error(`Unable to fill controlled input with value \"${value}\"`)\n}\n\nexport async function waitForApiMutation(\n page: Page,\n pathFragment: string,\n action: () => Promise<void>,\n method: 'POST' | 'PUT' | 'PATCH' | 'DELETE' = 'POST',\n timeoutMs = DEFAULT_UI_TIMEOUT_MS,\n): Promise<Response> {\n const responsePromise = page.waitForResponse(\n (response) =>\n response.request().method() === method &&\n response.url().includes(pathFragment),\n { timeout: timeoutMs },\n )\n\n await action()\n return responsePromise\n}\n"],
5
- "mappings": "AAAA,SAAS,cAAsD;AAE/D,MAAM,wBAAwB;AAE9B,eAAsB,oBACpB,OACA,OACA,YAAY,uBACG;AACf,QAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,MAAI,YAAqB;AAEzB,SAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,QAAI;AACF,YAAM,MAAM,uBAAuB,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACnD,YAAM,MAAM,MAAM,EAAE,SAAS,IAAM,CAAC;AACpC,YAAM,MAAM,KAAK,KAAK;AACtB,YAAM,OAAO,KAAK,EAAE,YAAY,OAAO,EAAE,SAAS,KAAM,CAAC;AACzD;AAAA,IACF,SAAS,OAAO;AACd,kBAAY;AACZ,YAAM,MAAM,KAAK,EAAE,eAAe,GAAG;AAAA,IACvC;AAAA,EACF;AAEA,MAAI,qBAAqB,OAAO;AAC9B,UAAM;AAAA,EACR;AACA,QAAM,IAAI,MAAM,+CAA+C,KAAK,GAAG;AACzE;AAEA,eAAsB,mBACpB,MACA,cACA,QACA,SAA8C,QAC9C,YAAY,uBACO;AACnB,QAAM,kBAAkB,KAAK;AAAA,IAC3B,CAAC,aACC,SAAS,QAAQ,EAAE,OAAO,MAAM,UAChC,SAAS,IAAI,EAAE,SAAS,YAAY;AAAA,IACtC,EAAE,SAAS,UAAU;AAAA,EACvB;AAEA,QAAM,OAAO;AACb,SAAO;AACT;",
4
+ "sourcesContent": ["import { expect, type Locator, type Page, type Response } from '@playwright/test'\n\nconst DEFAULT_UI_TIMEOUT_MS = 10_000\n\n// A React-controlled input renders whatever its state says. A fill that lands\n// before hydration writes only the DOM, and the hydration render then restores\n// the initial state value \u2014 the field empties again a few dozen milliseconds\n// later, with the same DOM node. Checking the value once right after the fill\n// reads the window before that happens and reports success on a value the app\n// is about to discard, which is how TC-UMES-E17 came to probe with an empty\n// person id and assert against whichever record the unfiltered query returned\n// first. Re-check after this settle window and let the loop retype.\nconst CONTROLLED_INPUT_SETTLE_MS = 400\n\nexport async function fillControlledInput(\n input: Locator,\n value: string,\n timeoutMs = DEFAULT_UI_TIMEOUT_MS,\n): Promise<void> {\n const deadline = Date.now() + timeoutMs\n let lastError: unknown = null\n\n while (Date.now() < deadline) {\n try {\n await input.scrollIntoViewIfNeeded().catch(() => {})\n await input.click({ timeout: 2_000 })\n await input.fill(value)\n await expect(input).toHaveValue(value, { timeout: 1_500 })\n await input.page().waitForTimeout(CONTROLLED_INPUT_SETTLE_MS)\n await expect(input).toHaveValue(value, { timeout: 1_500 })\n return\n } catch (error) {\n lastError = error\n await input.page().waitForTimeout(150)\n }\n }\n\n if (lastError instanceof Error) {\n throw lastError\n }\n throw new Error(`Unable to fill controlled input with value \"${value}\"`)\n}\n\nexport async function waitForApiMutation(\n page: Page,\n pathFragment: string,\n action: () => Promise<void>,\n method: 'POST' | 'PUT' | 'PATCH' | 'DELETE' = 'POST',\n timeoutMs = DEFAULT_UI_TIMEOUT_MS,\n): Promise<Response> {\n const responsePromise = page.waitForResponse(\n (response) =>\n response.request().method() === method &&\n response.url().includes(pathFragment),\n { timeout: timeoutMs },\n )\n\n await action()\n return responsePromise\n}\n"],
5
+ "mappings": "AAAA,SAAS,cAAsD;AAE/D,MAAM,wBAAwB;AAU9B,MAAM,6BAA6B;AAEnC,eAAsB,oBACpB,OACA,OACA,YAAY,uBACG;AACf,QAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,MAAI,YAAqB;AAEzB,SAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,QAAI;AACF,YAAM,MAAM,uBAAuB,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACnD,YAAM,MAAM,MAAM,EAAE,SAAS,IAAM,CAAC;AACpC,YAAM,MAAM,KAAK,KAAK;AACtB,YAAM,OAAO,KAAK,EAAE,YAAY,OAAO,EAAE,SAAS,KAAM,CAAC;AACzD,YAAM,MAAM,KAAK,EAAE,eAAe,0BAA0B;AAC5D,YAAM,OAAO,KAAK,EAAE,YAAY,OAAO,EAAE,SAAS,KAAM,CAAC;AACzD;AAAA,IACF,SAAS,OAAO;AACd,kBAAY;AACZ,YAAM,MAAM,KAAK,EAAE,eAAe,GAAG;AAAA,IACvC;AAAA,EACF;AAEA,MAAI,qBAAqB,OAAO;AAC9B,UAAM;AAAA,EACR;AACA,QAAM,IAAI,MAAM,+CAA+C,KAAK,GAAG;AACzE;AAEA,eAAsB,mBACpB,MACA,cACA,QACA,SAA8C,QAC9C,YAAY,uBACO;AACnB,QAAM,kBAAkB,KAAK;AAAA,IAC3B,CAAC,aACC,SAAS,QAAQ,EAAE,OAAO,MAAM,UAChC,SAAS,IAAI,EAAE,SAAS,YAAY;AAAA,IACtC,EAAE,SAAS,UAAU;AAAA,EACvB;AAEA,QAAM,OAAO;AACb,SAAO;AACT;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.6.8-develop.6930.1.1e5976efc3",
3
+ "version": "0.6.8-develop.6931.1.4a1e1c786b",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -254,16 +254,16 @@
254
254
  "zod": "^4.4.3"
255
255
  },
256
256
  "peerDependencies": {
257
- "@open-mercato/ai-assistant": "0.6.8-develop.6930.1.1e5976efc3",
258
- "@open-mercato/shared": "0.6.8-develop.6930.1.1e5976efc3",
259
- "@open-mercato/ui": "0.6.8-develop.6930.1.1e5976efc3",
257
+ "@open-mercato/ai-assistant": "0.6.8-develop.6931.1.4a1e1c786b",
258
+ "@open-mercato/shared": "0.6.8-develop.6931.1.4a1e1c786b",
259
+ "@open-mercato/ui": "0.6.8-develop.6931.1.4a1e1c786b",
260
260
  "react": "^19.0.0",
261
261
  "react-dom": "^19.0.0"
262
262
  },
263
263
  "devDependencies": {
264
- "@open-mercato/ai-assistant": "0.6.8-develop.6930.1.1e5976efc3",
265
- "@open-mercato/shared": "0.6.8-develop.6930.1.1e5976efc3",
266
- "@open-mercato/ui": "0.6.8-develop.6930.1.1e5976efc3",
264
+ "@open-mercato/ai-assistant": "0.6.8-develop.6931.1.4a1e1c786b",
265
+ "@open-mercato/shared": "0.6.8-develop.6931.1.4a1e1c786b",
266
+ "@open-mercato/ui": "0.6.8-develop.6931.1.4a1e1c786b",
267
267
  "@testing-library/dom": "^10.4.1",
268
268
  "@testing-library/jest-dom": "^7.0.0",
269
269
  "@testing-library/react": "^16.3.1",
@@ -2,6 +2,16 @@ import { expect, type Locator, type Page, type Response } from '@playwright/test
2
2
 
3
3
  const DEFAULT_UI_TIMEOUT_MS = 10_000
4
4
 
5
+ // A React-controlled input renders whatever its state says. A fill that lands
6
+ // before hydration writes only the DOM, and the hydration render then restores
7
+ // the initial state value — the field empties again a few dozen milliseconds
8
+ // later, with the same DOM node. Checking the value once right after the fill
9
+ // reads the window before that happens and reports success on a value the app
10
+ // is about to discard, which is how TC-UMES-E17 came to probe with an empty
11
+ // person id and assert against whichever record the unfiltered query returned
12
+ // first. Re-check after this settle window and let the loop retype.
13
+ const CONTROLLED_INPUT_SETTLE_MS = 400
14
+
5
15
  export async function fillControlledInput(
6
16
  input: Locator,
7
17
  value: string,
@@ -16,6 +26,8 @@ export async function fillControlledInput(
16
26
  await input.click({ timeout: 2_000 })
17
27
  await input.fill(value)
18
28
  await expect(input).toHaveValue(value, { timeout: 1_500 })
29
+ await input.page().waitForTimeout(CONTROLLED_INPUT_SETTLE_MS)
30
+ await expect(input).toHaveValue(value, { timeout: 1_500 })
19
31
  return
20
32
  } catch (error) {
21
33
  lastError = error