Files
coder/site/e2e/hooks.ts
T
Danny Kopping 2d36b587c0 chore(site): log errors when page fails with not_available in e2e tests (#16219)
https://github.com/coder/internal/issues/279 tracks a flake we've been
seeing of late.

I noticed log lines like these:

```
[onResponse] url=http://localhost:3111/api/v2/workspaces/2fedd3ad-58a9-49be-9e61-177878be7611/watch status=200 body=not_available
[onResponse] url=http://localhost:3111/api/v2/workspaceagents/753ee86d-46cb-4641-97f6-7b4c9c9a9e27/watch-metadata status=200 body=not_available
```

No other debugging info seems to be available for these responses, so
let's add some.

Signed-off-by: Danny Kopping <danny@coder.com>
2025-01-22 10:27:03 +02:00

89 lines
2.4 KiB
TypeScript

import http from "node:http";
import type { BrowserContext, Page } from "@playwright/test";
import { coderPort, gitAuth } from "./constants";
export const beforeCoderTest = (page: Page) => {
page.on("console", (msg) => console.info(`[onConsole] ${msg.text()}`));
page.on("request", (request) => {
if (!isApiCall(request.url())) {
return;
}
console.info(
`[onRequest] method=${request.method()} url=${request.url()} postData=${
request.postData() ? request.postData() : ""
}`,
);
});
page.on("response", async (response) => {
if (!isApiCall(response.url())) {
return;
}
const shouldLogResponse =
!response.url().endsWith("/api/v2/deployment/config") &&
!response.url().endsWith("/api/v2/debug/health?force=false");
let responseText = "";
try {
if (shouldLogResponse) {
const buffer = await response.body();
responseText = buffer.toString("utf-8");
responseText = responseText.replace(/\n$/g, "");
} else {
responseText = "skipped...";
}
} catch (error) {
console.error(error);
responseText = "not_available";
}
console.info(
`[onResponse] url=${response.url()} status=${response.status()} body=${responseText}`,
);
});
};
export const resetExternalAuthKey = async (context: BrowserContext) => {
// Find the session token so we can destroy the external auth link between tests, to ensure valid authentication happens each time.
const cookies = await context.cookies();
const sessionCookie = cookies.find((c) => c.name === "coder_session_token");
const options = {
method: "DELETE",
hostname: "127.0.0.1",
port: coderPort,
path: `/api/v2/external-auth/${gitAuth.webProvider}?coder_session_token=${sessionCookie?.value}`,
};
const req = http.request(options, (res) => {
let data = "";
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
// Both 200 (key deleted successfully) and 500 (key was not found) are valid responses.
if (res.statusCode !== 200 && res.statusCode !== 500) {
console.error("failed to delete external auth link", data);
throw new Error(
`failed to delete external auth link: HTTP response ${res.statusCode}`,
);
}
});
});
req.on("error", (err) => {
throw err.message;
});
req.end();
};
const isApiCall = (urlString: string): boolean => {
const url = new URL(urlString);
const apiPath = "/api/v2";
return url.pathname.startsWith(apiPath);
};