Sfoglia il codice sorgente

Prevent stability ping values from freezing on long tests (#851)

* Initial plan

* Clear stability ping resource timings

Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>

* Add CORS headers to route fulfillment in stability test

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
Co-authored-by: sstidl <sstidl@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot 1 settimana fa
parent
commit
fa2e28626a
2 ha cambiato i file con 43 aggiunte e 0 eliminazioni
  1. 4 0
      stability_worker.js
  2. 39 0
      tests/e2e/stability.spec.js

+ 4 - 0
stability_worker.js

@@ -185,6 +185,10 @@ function doPing() {
         if (d > 0 && d < instspd) instspd = d;
       } catch (e) {
         // Performance API not available, use estimate
+      } finally {
+        try {
+          performance.clearResourceTimings();
+        } catch (e) {}
       }
     }
 

+ 39 - 0
tests/e2e/stability.spec.js

@@ -1,8 +1,11 @@
 const fs = require("node:fs");
+const path = require("node:path");
 const { test, expect } = require("@playwright/test");
 const { baseUrls } = require("./helpers/env");
 const { stabilityStartButton } = require("./helpers/ui");
 
+const workerSource = fs.readFileSync(path.join(__dirname, "..", "..", "stability_worker.js"), "utf8");
+
 async function setShortDuration(page) {
   await page.evaluate(() => {
     const select = document.querySelector("#durationSelect");
@@ -122,4 +125,40 @@ test.describe("Stability test", () => {
     await expect(page.locator("#serverArea")).toBeVisible({ timeout: 10_000 });
     await expect(page.locator("#server option")).toContainText("Local dual backend", { timeout: 10_000 });
   });
+
+  test("clears resource timings after measuring a ping", async ({ page }) => {
+    await page.goto(`${baseUrls.standalone}/stability.html`);
+    await page.route(`${baseUrls.backend}/empty.php?cors=true&r=*`, route => route.fulfill({ status: 200, headers: { "Access-Control-Allow-Origin": "*" }, body: "" }));
+
+    await expect(
+      page.evaluate(
+        async ({ source, url }) => {
+          const instrumentedSource = `
+          const clearResourceTimings = performance.clearResourceTimings.bind(performance);
+          performance.clearResourceTimings = () => {
+            postMessage("resource timings cleared");
+            clearResourceTimings();
+          };
+          ${source}
+        `;
+          const worker = new Worker(URL.createObjectURL(new Blob([instrumentedSource], { type: "text/javascript" })));
+          try {
+            await new Promise((resolve, reject) => {
+              const timeout = setTimeout(() => reject(new Error("Resource timings were not cleared")), 10_000);
+              worker.onmessage = event => {
+                if (event.data === "resource timings cleared") {
+                  clearTimeout(timeout);
+                  resolve();
+                }
+              };
+              worker.postMessage(`start ${JSON.stringify({ url_ping: url, duration: 1, mpot: true })}`);
+            });
+          } finally {
+            worker.terminate();
+          }
+        },
+        { source: workerSource, url: `${baseUrls.backend}/empty.php` }
+      )
+    ).resolves.toBeUndefined();
+  });
 });