@capillarytech/cap-ui-utils 3.2.0-beta.2 → 3.2.0-beta.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/e2e/README.md CHANGED
@@ -64,6 +64,11 @@ import { waitForApi } from '@capillarytech/cap-ui-utils/e2e/playwright/waits';
64
64
  - **`playwright/logCollector`** — per-test POST to `http://127.0.0.1:4000/logger`
65
65
  with the exact WDIO payload (`status` / `time` / `validataionMessage` / `total`,
66
66
  keyed runId → suite → test). Non-fatal on any failure; honours `skipLogCollector`.
67
+ - **`playwright/apiFailureLogger`** — logs every same-origin API response outside
68
+ 2xx (response + request headers) and network-level request failures, with the
69
+ same wording as the WDIO CDP interceptor (`API <url> errored with status: ...`,
70
+ `Following request headers were sent for failed request`). Auto-attached by
71
+ `doLogin()`; also exported standalone as `attachApiFailureLogger(page, {baseUrl})`.
67
72
  - **`playwright/config`** — `createPlaywrightConfig()` wires the reporter, selects the
68
73
  suite via `SUITE` → `@<suite>` grep (mirrors `wdio --suite`), and sets pod-friendly
69
74
  defaults (headless chromium, trace/screenshot on failure, retries).
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ /**
3
+ * Failed-API logger — Playwright port of the WDIO base-conf network interceptor
4
+ * (test/wdio.conf.ts `Network.responseReceived` block): every SAME-ORIGIN API
5
+ * response outside 2xx is logged with its response + request headers, and
6
+ * network-level request failures (refused/aborted/DNS) are logged too.
7
+ *
8
+ * The lines go to stdout, which supervisor.py captures and ships to Apitester —
9
+ * and they use the SAME wording as the WDIO interceptor so existing debugging
10
+ * habits and log greps keep working:
11
+ *
12
+ * API <url> errored with status: <status> with following response headers:
13
+ * { ...response headers... }
14
+ * Following request headers were sent for failed request { ...request headers... }
15
+ *
16
+ * Auto-attached by doLogin() for every consumer (mirrors WDIO's always-on base
17
+ * conf). Idempotent per page. Logging must never fail the run.
18
+ */
19
+
20
+ const attached = new WeakSet();
21
+
22
+ function attachApiFailureLogger(page, opts = {}) {
23
+ if (!page || typeof page.on !== "function" || attached.has(page)) return;
24
+ attached.add(page);
25
+
26
+ // Same-origin filter — WDIO used cons['url'] (the intouch base URL).
27
+ const base = String(opts.baseUrl || process.env.INTOUCH_URL || "");
28
+
29
+ page.on("response", (response) => {
30
+ Promise.resolve()
31
+ .then(async () => {
32
+ const url = response.url();
33
+ if (base && !url.startsWith(base)) return;
34
+ const status = response.status();
35
+ if (status >= 200 && status <= 299) return;
36
+ const respHeaders = await response.allHeaders().catch(() => response.headers());
37
+ console.log(`API ${url} errored with status: ${status} with following response headers:`);
38
+ console.log(respHeaders);
39
+ console.log("Following request headers were sent for failed request", response.request().headers());
40
+ })
41
+ .catch(() => { /* logging must never fail the run */ });
42
+ });
43
+
44
+ page.on("requestfailed", (request) => {
45
+ try {
46
+ const url = request.url();
47
+ if (base && !url.startsWith(base)) return;
48
+ const failure = request.failure();
49
+ console.log(`API ${url} FAILED at network level: ${(failure && failure.errorText) || "unknown"} (method ${request.method()})`);
50
+ console.log("Following request headers were sent for failed request", request.headers());
51
+ } catch (e) { /* ignore */ }
52
+ });
53
+
54
+ console.log("----DONE SETTING UP NETWORK INTERCEPTOR TO LOG FAILED APIS----");
55
+ }
56
+
57
+ module.exports = { attachApiFailureLogger };
58
+ module.exports.default = { attachApiFailureLogger };
@@ -10,6 +10,7 @@ const config_1 = require("./config");
10
10
  const login_1 = require("./login");
11
11
  const waits_1 = require("./waits");
12
12
  const logCollector_1 = require("./logCollector");
13
+ const apiFailureLogger_1 = require("./apiFailureLogger");
13
14
 
14
15
  exports.createPlaywrightConfig = config_1.createPlaywrightConfig;
15
16
  exports.doLogin = login_1.doLogin;
@@ -17,4 +18,5 @@ exports.waitForApi = waits_1.waitForApi;
17
18
  exports.clickAndWaitForApi = waits_1.clickAndWaitForApi;
18
19
  exports.waitForApiIdle = waits_1.waitForApiIdle;
19
20
  exports.collectLogs = logCollector_1.collectLogs;
21
+ exports.attachApiFailureLogger = apiFailureLogger_1.attachApiFailureLogger;
20
22
  exports.reporterPath = require.resolve("./reporter");
@@ -10,6 +10,8 @@
10
10
  * import { doLogin } from '@capillarytech/cap-ui-utils/e2e/playwright/login';
11
11
  * await doLogin(page, { url, username, password });
12
12
  */
13
+ const { attachApiFailureLogger } = require("./apiFailureLogger");
14
+
13
15
  const MAX_LOGIN_ATTEMPTS = 3;
14
16
 
15
17
  function sel(page) {
@@ -28,6 +30,9 @@ function sel(page) {
28
30
 
29
31
  async function doLogin(page, opts, attempt = 0) {
30
32
  const { url, username, password } = opts;
33
+ // WDIO's base conf always logged failed same-origin API calls (CDP interceptor);
34
+ // wire the PW equivalent here so every consumer inherits it. Idempotent per page.
35
+ attachApiFailureLogger(page, { baseUrl: url });
31
36
  const s = sel(page);
32
37
  try {
33
38
  await page.goto(url, { waitUntil: "domcontentloaded" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capillarytech/cap-ui-utils",
3
- "version": "3.2.0-beta.2",
3
+ "version": "3.2.0-beta.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },