File size: 3,035 Bytes
88d2f2a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Focused re-test of the Trigger flow using waitForURL (event-driven, not
// poll-based) to distinguish a real cross-browser bug from a test-timing
// artifact. Writes results into outputs/cross_browser_trigger_recheck.json.
const fs = require("fs");
const path = require("path");
const { chromium, firefox, webkit } = require("playwright");

const BASE_URL = process.env.BASE_URL || "http://localhost:3001";
const OUT_DIR = path.resolve(__dirname, "..", "..", "outputs");
const SHOT_DIR = path.join(OUT_DIR, "screenshots");
fs.mkdirSync(SHOT_DIR, { recursive: true });

const ENGINES = [
  { name: "chromium", launcher: chromium },
  { name: "firefox", launcher: firefox },
  { name: "webkit", launcher: webkit },
];

async function run(engine) {
  const browser = await engine.launcher.launch({ headless: true });
  const ctx = await browser.newContext({ viewport: { width: 1280, height: 800 }, colorScheme: "dark" });
  const page = await ctx.newPage();
  const errors = [];
  const postResponses = [];
  page.on("console", (m) => m.type() === "error" && errors.push(m.text()));
  page.on("pageerror", (e) => errors.push(`pageerror: ${e.message}`));
  page.on("response", async (r) => {
    if (r.request().method() === "POST" && /trigger/.test(r.url())) {
      postResponses.push({ url: r.url(), status: r.status() });
    }
  });

  const out = {
    browser: engine.name, postReceived: false, postStatus: null,
    waitForURLSucceeded: false, finalUrl: null, msToNavigate: null,
    spinnerSeen: false, errors: [],
  };

  try {
    await page.goto(`${BASE_URL}/`, { waitUntil: "domcontentloaded", timeout: 30000 });
    const btn = page.getByRole("button", { name: /trigger.*live demo/i });
    await btn.waitFor({ state: "visible", timeout: 10000 });
    const t0 = Date.now();
    await btn.click();
    try { await page.waitForSelector(".animate-spin", { timeout: 1500 }); out.spinnerSeen = true; } catch (_) {}
    try {
      await page.waitForURL(/\/events\/\d+/, { timeout: 30000 });
      out.waitForURLSucceeded = true;
      out.finalUrl = page.url();
      out.msToNavigate = Date.now() - t0;
    } catch (err) {
      out.errors.push(`waitForURL: ${err.message}`);
    }
    if (postResponses.length > 0) {
      out.postReceived = true;
      out.postStatus = postResponses[0].status;
    }
    const shot = path.join(SHOT_DIR, `xbrowser_${engine.name}_trigger_recheck.png`);
    await page.screenshot({ path: shot });
    out.screenshot = path.relative(OUT_DIR, shot);
  } catch (err) {
    out.errors.push(err.message);
  } finally {
    out.errors.push(...errors.slice(0, 3));
    await ctx.close();
    await browser.close();
  }
  return out;
}

(async () => {
  const all = [];
  for (const engine of ENGINES) {
    console.log(`-- ${engine.name} --`);
    const r = await run(engine);
    console.log(JSON.stringify(r));
    all.push(r);
  }
  const out = path.join(OUT_DIR, "cross_browser_trigger_recheck.json");
  fs.writeFileSync(out, JSON.stringify(all, null, 2));
  console.log(`Wrote ${out}`);
})();