mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-24 01:41:42 +02:00
Add long-thread issue chat perf fixture
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
647c2c487e
commit
a2be4580ae
8 files changed
+636
-8
No files matched your search
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { chromium } from "@playwright/test";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
const baseUrl = (process.env.PAPERCLIP_PERF_BASE_URL || "http://localhost:3100").replace(/\/$/, "");
|
||||
const companyPrefix = process.env.PAPERCLIP_PERF_COMPANY_PREFIX;
|
||||
const url = companyPrefix
|
||||
? `${baseUrl}/${companyPrefix}/tests/perf/long-thread`
|
||||
: `${baseUrl}/tests/perf/long-thread`;
|
||||
const origin = new URL(url).origin;
|
||||
|
||||
function loadBoardToken() {
|
||||
const authPath = path.resolve(os.homedir(), ".paperclip/auth.json");
|
||||
try {
|
||||
const auth = JSON.parse(fs.readFileSync(authPath, "utf-8"));
|
||||
const credentials = auth.credentials || {};
|
||||
const matching = Object.values(credentials).find((entry) => {
|
||||
if (!entry || !entry.token || !entry.apiBase) return false;
|
||||
return new URL(entry.apiBase).origin === origin;
|
||||
});
|
||||
if (matching?.token) return matching.token;
|
||||
const fallback = Object.values(credentials).find((entry) => entry?.token);
|
||||
return fallback?.token ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const browser = await chromium.launch({ headless: true });
|
||||
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
|
||||
const boardToken = process.env.PAPERCLIP_PERF_BEARER_TOKEN || loadBoardToken();
|
||||
|
||||
if (boardToken) {
|
||||
await page.route(`${origin}/**`, async (route) => {
|
||||
await route.continue({
|
||||
headers: { ...route.request().headers(), Authorization: `Bearer ${boardToken}` },
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const startedAt = Date.now();
|
||||
await page.goto(url, { waitUntil: "networkidle" });
|
||||
await page.waitForSelector('[data-testid="issue-chat-long-thread-perf"]', { timeout: 30_000 });
|
||||
await page.waitForFunction(() => {
|
||||
const target = Number(document.querySelector('[data-testid="perf-fixture-row-target"]')?.textContent ?? "450");
|
||||
return document.querySelectorAll('[data-testid="issue-chat-message-row"]').length >= target;
|
||||
}, null, { timeout: 60_000 });
|
||||
const rowReadyMs = Date.now() - startedAt;
|
||||
|
||||
const metrics = await page.evaluate(async () => {
|
||||
const text = (testId) => document.querySelector(`[data-testid="${testId}"]`)?.textContent?.trim() ?? "";
|
||||
const numericMs = (testId) => {
|
||||
const value = text(testId).replace(/\s*ms$/, "");
|
||||
const parsed = Number(value);
|
||||
return Number.isFinite(parsed) ? parsed : null;
|
||||
};
|
||||
|
||||
const rowCount = document.querySelectorAll('[data-testid="issue-chat-message-row"]').length;
|
||||
const assistantRowCount = document.querySelectorAll('[data-testid="issue-chat-message-row"][data-message-role="assistant"]').length;
|
||||
const systemRowCount = document.querySelectorAll('[data-testid="issue-chat-message-row"][data-message-role="system"]').length;
|
||||
const userRowCount = document.querySelectorAll('[data-testid="issue-chat-message-row"][data-message-role="user"]').length;
|
||||
const markdownRows = Number(text("perf-fixture-markdown-rows"));
|
||||
const commitCount = Number(text("perf-commit-count"));
|
||||
const scrollStartY = window.scrollY;
|
||||
const scrollTarget = Math.max(0, document.documentElement.scrollHeight - window.innerHeight);
|
||||
const scrollStartedAt = performance.now();
|
||||
window.scrollTo({ top: scrollTarget, behavior: "instant" });
|
||||
await new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
||||
await new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
||||
const scrollResponsiveMs = performance.now() - scrollStartedAt;
|
||||
|
||||
return {
|
||||
url: window.location.href,
|
||||
fixtureRowTarget: Number(text("perf-fixture-row-target")),
|
||||
rowCount,
|
||||
assistantRowCount,
|
||||
userRowCount,
|
||||
systemRowCount,
|
||||
markdownRows,
|
||||
commitCount,
|
||||
mountActualDurationMs: numericMs("perf-mount-duration"),
|
||||
latestActualDurationMs: numericMs("perf-latest-duration"),
|
||||
maxActualDurationMs: numericMs("perf-max-duration"),
|
||||
totalActualDurationMs: numericMs("perf-total-duration"),
|
||||
reactProfilerAvailable: commitCount > 0,
|
||||
scrollResponsiveMs: Number(scrollResponsiveMs.toFixed(1)),
|
||||
scrollDeltaPx: Math.round(Math.abs(window.scrollY - scrollStartY)),
|
||||
documentHeightPx: Math.round(document.documentElement.scrollHeight),
|
||||
};
|
||||
});
|
||||
|
||||
const elapsedMs = Date.now() - startedAt;
|
||||
console.log(JSON.stringify({ ...metrics, renderReadyMs: rowReadyMs, elapsedMs }, null, 2));
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
Reference in new issue
Block a user