fix(insomnia-test): address Copilot review comments

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Bob QiuandClaude Sonnet 5.5 committed 2026-11-02 13:10:07 +08:00
1 parent 0e51db2b51
commit ca4ed234e1
7 files changed
+48 -30

No files matched your search

+1 -1
View File
@@ -27326,7 +27326,7 @@
"@grpc/grpc-js": "^1.14.4",
"@grpc/reflection": "^1.0.4",
"@modelcontextprotocol/sdk": "^1.29.0",
"@playwright/test": "1.59.1",
"@playwright/test": "1.63.0",
"@types/node": "^26.0.1",
"electron": "^43.2.0",
"express": "^5.2.1",
@@ -121,7 +121,7 @@ export class HttpRequestFlow extends BaseFlow {
await page.setBody(request.body);
}
if (request.authentication) {
await this.applyAuthentication(page, request.authentication);
await this.applyHttpAuthentication(page, request.authentication);
}
if (request.preRequestScript || request.afterResponseScript) {
await page.scripts.setScripts({
@@ -132,22 +132,21 @@ export class HttpRequestFlow extends BaseFlow {
}
/**
* Applies `authentication` to the request pane's Auth tab. Only OAuth
* 1.0 and OAuth 2.0 are wired up so far — other auth types will need
* their own Page setter before they can be added here.
* Applies `authentication` to the request pane's Auth tab. OAuth 1.0 is
* HTTP-only so it is handled here; every other type is delegated to
* `BaseFlow.applyAuthentication`.
* @param page - The request page to apply authentication on
* @param authentication - The authentication config to apply
*/
private async applyAuthentication(
private async applyHttpAuthentication(
page: HttpRequestPage,
authentication: RequestAuthentication,
): Promise<void> {
if (authentication.type === "oauth1") {
await page.auth.setOAuth1Fields(authentication);
return;
}
if (authentication.type === "oauth2") {
await page.auth.setOAuth2Fields(authentication);
}
await this.applyAuthentication(page.auth, authentication);
}
}
+22
View File
@@ -418,6 +418,7 @@ export const test = base.extend<Fixtures>({
user: async (
{ window, insomnia, gitCloneUrl, dataPath, skipOnboarding, vaultKey, vaultSalt },
use,
testInfo,
) => {
const pageManager = new PageManager(window, insomnia);
const flowManager = new FlowManager(pageManager, insomnia, gitCloneUrl, {
@@ -430,6 +431,27 @@ export const test = base.extend<Fixtures>({
await disableFocusModeDefault(flowManager);
await use({ page: window, pageManager, flowManager });
await closeOpenStepGroup();
// A test that called AppFlow.restart() leaves the relaunched app
// behind — the `insomnia`/`window` fixtures only know the original
// handles. Collect its coverage and close it here, before they tear down.
const currentApp = flowManager.electronApp;
if (currentApp && currentApp !== insomnia) {
const currentWindow = await currentApp
.firstWindow({ timeout: DEFAULT_TIMEOUT })
.catch(() => null);
if (currentWindow) {
if (testInfo.status !== testInfo.expectedStatus) {
await testInfo.attach("screenshot-after-restart", {
body: await currentWindow.screenshot().catch(() => Buffer.alloc(0)),
contentType: "image/png",
});
}
await collectWindowCoverage(currentWindow);
}
await collectHiddenWindowCoverage(currentApp);
await currentApp.close().catch(() => {});
}
},
});
@@ -43,14 +43,17 @@ export class EventStreamRequestPage extends RequestPage {
/**
* Navigates to the event-stream request pane, then installs a
* `db.changes` listener that increments `window.__saveCount` each time a
* "Request" document is saved — used by tests to assert save behavior
* without polling the UI.
* `db.changes` listener (once per window) that increments
* `window.__saveCount` each time a "Request" document is saved — used by
* tests to assert save behavior without polling the UI. Repeat calls
* only reset the counter.
*/
async navigate(): Promise<void> {
await super.navigate();
await this.page.evaluate(() => {
(window as any).__saveCount = 0;
if ((window as any).__saveCountListenerInstalled) return;
(window as any).__saveCountListenerInstalled = true;
(window as any).main.on(
"db.changes",
(_: unknown, changes: [string, { type: string }][]) => {
@@ -112,6 +112,11 @@ export abstract class RequestPage extends TabPanelPage {
.locator(this.PANE)
.getByRole("button", { name: /^(Connect|Disconnect)$/ });
await connectButton.click();
await expect(
this.page
.locator(this.PANE)
.getByRole("button", { name: "Disconnect", exact: true }),
).toBeVisible({ timeout: DEFAULT_TIMEOUT });
}
/**
@@ -317,11 +317,16 @@ export class ResponsePage extends BasePage {
/**
* Confirms a gRPC response has been rendered by waiting for the
* response status tag to become visible.
* response status tag to become visible. If an error dialog appears
* instead (gRPC business failures), throws using its text.
*/
async navigateGrpc(): Promise<void> {
const statusTag = this.page.locator(`${this.PANE} [data-testid="response-status-tag"]`);
await expect(statusTag).toBeVisible({ timeout: DEFAULT_TIMEOUT });
const dialog = this.page.getByRole('dialog').first();
await statusTag.or(dialog).first().waitFor({ state: 'visible', timeout: DEFAULT_TIMEOUT });
if (await dialog.isVisible()) {
throw new Error((await dialog.innerText()).trim());
}
}
private async switchTab(tab: ResponseTab): Promise<boolean> {
@@ -1,6 +1,3 @@
import { expect } from "@playwright/test";
import { DEFAULT_TIMEOUT } from "../misc/constants";
import type { RequestHeader,SocketIOMessage } from "../models/socket-io-request";
import { RequestPage } from "./request.page";
@@ -8,19 +5,6 @@ export class SocketIORequestPage extends RequestPage {
protected readonly urlBarId = "websocket-url-bar";
protected readonly persistedDbFile = "insomnia.SocketIORequest.db";
/**
* Clicks Connect and waits for the button to flip to "Disconnect", so a
* following send doesn't race the handshake and get dropped.
*/
async connect(): Promise<void> {
await super.connect();
await expect(
this.page
.locator(this.PANE)
.getByRole("button", { name: "Disconnect", exact: true }),
).toBeVisible({ timeout: DEFAULT_TIMEOUT });
}
/**
* Reads the full Socket.IO request state from the UI (url, headers, and
* the composed message).