Skip unrelated required checks without losing their names (#2542)

* fix(ci): skip unrelated required checks cleanly

Matrix jobs had to start no-op runners to preserve interpolated required-check names. Static named jobs let GitHub report genuine skipped conclusions while keeping those names stable.

* fix(ci): gate changes to install patching script

* fix(ci): route cross-package test contracts narrowly

* fix(ci): keep routed contracts merge-blocking

* fix(server): exclude nested test utilities from builds

* fix(ci): cover app-owned native and browser domains

* refactor(ci): align tests with runtime domains

Own browser specs, desktop specs, and Electron-only app code by stable directories so PR routing does not depend on filename conventions. Keep desktop integration coverage inside the required desktop check.

* fix(ci): keep routing and desktop suites isolated

The routing regression must run before dependency installation, and desktop Vitest must not collect Playwright-owned specs.

* fix(ci): isolate desktop e2e runtime

* perf(test): isolate Playwright workers

* perf(test): parallelize Playwright within specs

* fix(test): keep Playwright file scheduling

* fix(test): share dynamic Metro fixture

* fix(test): preserve own-host restart fixtures

* fix(ci): preserve routed contracts after rebase

* Stabilize Playwright wheel-scroll assertions
This commit is contained in:
Mohamed Boudra
2026-08-02 00:56:05 +08:00
committed by GitHub
parent 429155b536
commit 5a30affd7f
256 changed files with 2693 additions and 2674 deletions
File diff suppressed because it is too large Load Diff
@@ -1,50 +0,0 @@
import { Text, View } from "react-native";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
interface BrowserPaneProps {
browserId: string;
serverId: string;
workspaceId: string;
cwd: string | null;
isInteractive?: boolean;
onFocusPane?: () => void;
}
export function BrowserPane({ browserId }: BrowserPaneProps) {
const { theme } = useUnistyles();
const { t } = useTranslation();
const titleStyle = useMemo(
() => [styles.title, { color: theme.colors.foreground }],
[theme.colors.foreground],
);
const subtitleStyle = useMemo(
() => [styles.subtitle, { color: theme.colors.foregroundMuted }],
[theme.colors.foregroundMuted],
);
return (
<View style={styles.container}>
<Text style={titleStyle}>{t("workspace.browser.unavailable.title")}</Text>
<Text style={subtitleStyle}>{t("workspace.browser.session", { browserId })}</Text>
</View>
);
}
const styles = StyleSheet.create(() => ({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
gap: 8,
padding: 16,
},
title: {
fontSize: 16,
fontWeight: "600",
},
subtitle: {
fontSize: 12,
},
}));
@@ -1,51 +0,0 @@
import { useMemo } from "react";
import { Text, View } from "react-native";
import { useTranslation } from "react-i18next";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
interface BrowserPaneProps {
browserId: string;
serverId: string;
workspaceId: string;
cwd: string | null;
isInteractive?: boolean;
onFocusPane?: () => void;
}
export function BrowserPane({ browserId }: BrowserPaneProps) {
const { t } = useTranslation();
const { theme } = useUnistyles();
const titleStyle = useMemo(
() => [styles.title, { color: theme.colors.foreground }],
[theme.colors.foreground],
);
const subtitleStyle = useMemo(
() => [styles.subtitle, { color: theme.colors.foregroundMuted }],
[theme.colors.foregroundMuted],
);
return (
<View style={styles.container}>
<Text style={titleStyle}>{t("workspace.browser.unavailable.title")}</Text>
<Text style={subtitleStyle}>{t("workspace.browser.unavailable.subtitle")}</Text>
<Text style={subtitleStyle}>{t("workspace.browser.session", { browserId })}</Text>
</View>
);
}
const styles = StyleSheet.create(() => ({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
gap: 8,
padding: 16,
},
title: {
fontSize: 16,
fontWeight: "600",
},
subtitle: {
fontSize: 12,
},
}));
@@ -1,288 +0,0 @@
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import {
type BrowserWebviewProfileHost,
clearResidentBrowserWebviewsForTests,
ensureResidentBrowserWebview,
getResidentBrowserWebview,
prepareBrowserWebview,
releaseResidentBrowserWebview,
removeResidentBrowserWebview,
takeResidentBrowserWebview,
} from "./browser-webview-resident";
import {
setCommandCenterFocusRestoreElement,
takeCommandCenterFocusRestoreElement,
} from "../utils/command-center-focus-restore";
const RESIDENT_HOST_ID = "paseo-browser-resident-webviews";
const attachedBrowsers: Array<{
browserId: string;
workspaceId: string;
webContentsId: number;
}> = [];
const profileHost: BrowserWebviewProfileHost = {
profilePartition: "persist:paseo-browser",
registerAttachedBrowser: async (input) => {
attachedBrowsers.push(input);
},
};
function ensureTestBrowser(input: {
browserId: string;
workspaceId: string;
url: string;
}): HTMLElement | null {
return ensureResidentBrowserWebview({ ...input, profileHost });
}
function prepareTestBrowser(
webview: HTMLElement,
input: { browserId: string; workspaceId: string; initialUrl?: string | null },
): void {
prepareBrowserWebview(webview, { ...input, profileHost });
}
function residentHost(): HTMLElement {
const host = document.getElementById(RESIDENT_HOST_ID);
if (!host) {
throw new Error("Expected resident browser host");
}
return host;
}
function expectPermanentHostParking(host: HTMLElement): void {
expect(host.style.position).toBe("fixed");
expect(host.style.left).toBe("0px");
expect(host.style.top).toBe("0px");
expect(host.style.width).toBe("1px");
expect(host.style.height).toBe("1px");
expect(host.style.overflow).toBe("hidden");
expect(host.style.opacity).toBe("1");
expect(host.style.pointerEvents).toBe("none");
expect(host.style.display).toBe("block");
expect(host.style.visibility).toBe("visible");
expect(host.style.transform).toBe("");
}
function expectResidentWebviewParking(webview: HTMLElement): void {
expect(webview.style.display).toBe("inline-flex");
expect(webview.style.flex).toBe("0 0 auto");
expect(webview.style.width).toBe("1280px");
expect(webview.style.height).toBe("800px");
expect(webview.style.position).toBe("absolute");
expect(webview.style.left).toBe("0px");
expect(webview.style.top).toBe("0px");
expect(webview.style.zIndex).toBe("0");
}
describe("resident browser webviews", () => {
beforeEach(() => {
attachedBrowsers.length = 0;
});
afterEach(() => {
clearResidentBrowserWebviewsForTests();
});
it("parks a browser webview in the permanent paintable 1x1 host", () => {
const visibleHost = document.createElement("div");
const webview = document.createElement("webview");
visibleHost.appendChild(webview);
document.body.appendChild(visibleHost);
releaseResidentBrowserWebview("browser-a", webview);
const host = residentHost();
expect(visibleHost.children).toHaveLength(0);
expect(Array.from(host.children)).toEqual([webview]);
expect(webview.isConnected).toBe(true);
expectPermanentHostParking(host);
expectResidentWebviewParking(webview);
});
it("creates a resident webview for an agent-created unfocused tab", () => {
const webview = ensureTestBrowser({
browserId: "browser-agent",
workspaceId: "workspace-agent",
url: "https://example.com",
});
expect(webview).not.toBeNull();
expect(webview?.isConnected).toBe(true);
expect(webview?.getAttribute("data-paseo-browser-id")).toBe("browser-agent");
expect(webview?.getAttribute("partition")).toBe("persist:paseo-browser");
expect((webview as HTMLUnknownElement & { src?: string })?.src).toContain(
"https://example.com",
);
expectPermanentHostParking(residentHost());
expectResidentWebviewParking(webview as HTMLElement);
});
it("shares one profile and registers attached guests with explicit identity", () => {
const firstWebview = ensureTestBrowser({
browserId: "browser-first",
workspaceId: "workspace-a",
url: "https://example.com/first",
});
const secondWebview = ensureTestBrowser({
browserId: "browser-second",
workspaceId: "workspace-b",
url: "https://example.com/second",
});
if (!firstWebview || !secondWebview) {
throw new Error("Expected resident webviews");
}
Object.assign(firstWebview, { getWebContentsId: () => 101 });
Object.assign(secondWebview, { getWebContentsId: () => 202 });
firstWebview.dispatchEvent(new Event("did-attach"));
secondWebview.dispatchEvent(new Event("did-attach"));
expect(firstWebview.getAttribute("partition")).toBe("persist:paseo-browser");
expect(secondWebview.getAttribute("partition")).toBe("persist:paseo-browser");
expect(attachedBrowsers).toEqual([
{ browserId: "browser-first", workspaceId: "workspace-a", webContentsId: 101 },
{ browserId: "browser-second", workspaceId: "workspace-b", webContentsId: 202 },
]);
});
it("normalizes an existing resident host back to permanent parking", () => {
const staleHost = document.createElement("div");
staleHost.id = RESIDENT_HOST_ID;
staleHost.style.left = "-20000px";
staleHost.style.width = "1280px";
staleHost.style.height = "800px";
staleHost.style.opacity = "0";
staleHost.style.display = "none";
document.body.appendChild(staleHost);
const webview = ensureTestBrowser({
browserId: "browser-stale-host",
workspaceId: "workspace-stale-host",
url: "https://example.com",
});
expect(webview).not.toBeNull();
expectPermanentHostParking(staleHost);
expectResidentWebviewParking(webview as HTMLElement);
});
it("normalizes an existing resident webview and its stale host before reusing them", () => {
const staleHost = document.createElement("div");
staleHost.id = RESIDENT_HOST_ID;
staleHost.style.left = "-20000px";
staleHost.style.width = "1280px";
staleHost.style.height = "800px";
staleHost.style.opacity = "0";
staleHost.style.display = "none";
const staleWebview = document.createElement("webview");
prepareTestBrowser(staleWebview, {
browserId: "browser-stale-child",
workspaceId: "workspace-stale-child",
initialUrl: "https://example.com",
});
staleWebview.style.display = "none";
staleWebview.style.width = "1px";
staleWebview.style.height = "1px";
staleWebview.style.position = "fixed";
staleWebview.style.left = "-20000px";
staleHost.appendChild(staleWebview);
document.body.appendChild(staleHost);
const webview = ensureTestBrowser({
browserId: "browser-stale-child",
workspaceId: "workspace-stale-child",
url: "https://example.com/agent",
});
expect(webview).toBe(staleWebview);
expect(Array.from(staleHost.children)).toEqual([staleWebview]);
expectPermanentHostParking(staleHost);
expectResidentWebviewParking(staleWebview);
});
it("parks resident webviews as an overlapping stack", () => {
const firstWebview = ensureTestBrowser({
browserId: "browser-first",
workspaceId: "workspace-stack",
url: "https://example.com/first",
});
const secondWebview = ensureTestBrowser({
browserId: "browser-second",
workspaceId: "workspace-stack",
url: "https://example.com/second",
});
const host = residentHost();
expect(firstWebview?.parentElement).toBe(host);
expect(secondWebview?.parentElement).toBe(host);
expectResidentWebviewParking(firstWebview as HTMLElement);
expectResidentWebviewParking(secondWebview as HTMLElement);
});
it("moves a resident webview into a visible pane without recreating the node", () => {
const webview = ensureTestBrowser({
browserId: "browser-visible",
workspaceId: "workspace-visible",
url: "https://example.com",
});
const visibleWebview = takeResidentBrowserWebview("browser-visible");
expect(visibleWebview).toBe(webview);
expect(webview?.style.position).toBe("");
expect(webview?.style.left).toBe("");
expect(webview?.style.top).toBe("");
expect(webview?.style.zIndex).toBe("");
expect(takeResidentBrowserWebview("browser-visible")).toBeNull();
});
it("returns an existing visible pane webview instead of creating a resident duplicate", () => {
const visibleHost = document.createElement("div");
const visibleWebview = document.createElement("webview");
prepareTestBrowser(visibleWebview, {
browserId: "browser-visible-pane",
workspaceId: "workspace-visible-pane",
initialUrl: "https://example.com",
});
visibleHost.appendChild(visibleWebview);
document.body.appendChild(visibleHost);
const webview = ensureTestBrowser({
browserId: "browser-visible-pane",
workspaceId: "workspace-visible-pane",
url: "https://example.com/agent",
});
expect(webview).toBe(visibleWebview);
expect(document.getElementById(RESIDENT_HOST_ID)).toBeNull();
});
it("finds the originating browser webview for focus restoration", () => {
const webview = ensureTestBrowser({
browserId: "browser-focus",
workspaceId: "workspace-focus",
url: "https://example.com",
});
setCommandCenterFocusRestoreElement(getResidentBrowserWebview("browser-focus"));
expect(takeCommandCenterFocusRestoreElement()).toBe(webview);
expect(getResidentBrowserWebview("browser-missing")).toBeNull();
});
it("removes a resident webview when its browser tab closes", () => {
const webview = ensureTestBrowser({
browserId: "browser-closed",
workspaceId: "workspace-closed",
url: "https://example.com",
});
removeResidentBrowserWebview("browser-closed");
expect(webview?.isConnected).toBe(false);
expect(takeResidentBrowserWebview("browser-closed")).toBeNull();
});
});
@@ -1,313 +0,0 @@
import {
getDesktopHost,
type DesktopAttachedBrowserRegistration,
type DesktopBrowserBridge,
} from "@/desktop/host";
const RESIDENT_BROWSER_HOST_ID = "paseo-browser-resident-webviews";
const BROWSER_ID_ATTRIBUTE = "data-paseo-browser-id";
const RESIDENT_VIEWPORT_WIDTH = 1280;
const RESIDENT_VIEWPORT_HEIGHT = 800;
const residentWebviewsByBrowserId = new Map<string, HTMLElement>();
const residentWebviewSizesByBrowserId = new Map<string, { width: number; height: number }>();
interface BrowserWebviewElement extends HTMLElement {
src: string;
getWebContentsId(): number;
}
interface BrowserWebviewIdentity {
browserId: string;
workspaceId: string;
}
export interface BrowserWebviewProfileHost {
profilePartition: string;
registerAttachedBrowser(input: DesktopAttachedBrowserRegistration): Promise<void>;
}
function isAttachedBrowserBridge(
browser: DesktopBrowserBridge | undefined,
): browser is BrowserWebviewProfileHost {
return (
browser !== undefined &&
typeof browser.profilePartition === "string" &&
browser.profilePartition.startsWith("persist:") &&
typeof browser.registerAttachedBrowser === "function"
);
}
function getBrowserBridge(override?: BrowserWebviewProfileHost): BrowserWebviewProfileHost {
if (override) {
return override;
}
const browser = getDesktopHost()?.browser;
if (!isAttachedBrowserBridge(browser)) {
throw new Error("Electron browser profile bridge is unavailable");
}
return browser;
}
function registerBrowserWhenAttached(
webview: BrowserWebviewElement,
identity: BrowserWebviewIdentity,
browser: BrowserWebviewProfileHost,
): void {
// Reparenting a webview can replace its guest WebContents without replacing
// this DOM element, so every attachment needs a fresh main-process registration.
webview.addEventListener("did-attach", () => {
const webContentsId = webview.getWebContentsId();
void browser
.registerAttachedBrowser({
browserId: identity.browserId,
workspaceId: identity.workspaceId,
webContentsId,
})
.catch((error) => {
console.error("[browser-webview] attached registration failed", error);
});
});
}
function trimNonEmpty(value: string | null | undefined): string | null {
if (typeof value !== "string") {
return null;
}
const trimmed = value.trim();
return trimmed.length > 0 ? trimmed : null;
}
function readDocument(): Document | null {
return typeof document === "undefined" ? null : document;
}
function applyResidentHostParkingStyle(host: HTMLElement): void {
// Parked browser webviews must remain paintable at all times; screenshot
// correctness depends on the proven states in docs/browser-capture-harness.md.
host.setAttribute("aria-hidden", "true");
host.style.position = "fixed";
host.style.left = "0";
host.style.top = "0";
host.style.width = "1px";
host.style.height = "1px";
host.style.overflow = "hidden";
host.style.opacity = "1";
host.style.pointerEvents = "none";
host.style.display = "block";
host.style.zIndex = "";
host.style.clipPath = "";
host.style.visibility = "visible";
host.style.transform = "";
}
function getResidentBrowserHost(ownerDocument: Document): HTMLElement {
const existing = ownerDocument.getElementById(RESIDENT_BROWSER_HOST_ID);
if (existing) {
applyResidentHostParkingStyle(existing);
return existing;
}
const host = ownerDocument.createElement("div");
host.id = RESIDENT_BROWSER_HOST_ID;
applyResidentHostParkingStyle(host);
ownerDocument.body.appendChild(host);
return host;
}
function findBrowserWebview(browserId: string, ownerDocument: Document): HTMLElement | null {
for (const element of ownerDocument.querySelectorAll(`[${BROWSER_ID_ATTRIBUTE}]`)) {
if (!(element instanceof HTMLElement)) {
continue;
}
if (element.getAttribute(BROWSER_ID_ATTRIBUTE) === browserId) {
return element;
}
}
return null;
}
function dimensionsForBrowser(browserId: string | null): { width: number; height: number } {
if (!browserId) {
return { width: RESIDENT_VIEWPORT_WIDTH, height: RESIDENT_VIEWPORT_HEIGHT };
}
return (
residentWebviewSizesByBrowserId.get(browserId) ?? {
width: RESIDENT_VIEWPORT_WIDTH,
height: RESIDENT_VIEWPORT_HEIGHT,
}
);
}
function applyResidentWebviewStyle(webview: HTMLElement, browserId: string | null): void {
const dimensions = dimensionsForBrowser(browserId);
webview.style.display = "inline-flex";
webview.style.flex = "0 0 auto";
webview.style.width = `${dimensions.width}px`;
webview.style.height = `${dimensions.height}px`;
webview.style.border = "0";
webview.style.background = "transparent";
webview.style.position = "absolute";
webview.style.left = "0";
webview.style.top = "0";
webview.style.marginTop = "0";
webview.style.zIndex = "0";
}
function clearResidentWebviewParkingStyle(webview: HTMLElement): void {
webview.style.position = "";
webview.style.left = "";
webview.style.top = "";
webview.style.marginTop = "";
webview.style.zIndex = "";
}
export function prepareBrowserWebview(
webview: HTMLElement,
input: {
browserId: string;
workspaceId: string;
initialUrl?: string | null;
profileHost?: BrowserWebviewProfileHost;
},
): void {
const browser = getBrowserBridge(input.profileHost);
webview.setAttribute(BROWSER_ID_ATTRIBUTE, input.browserId);
webview.setAttribute("partition", browser.profilePartition);
webview.setAttribute("allowpopups", "true");
webview.setAttribute("spellcheck", "false");
webview.setAttribute("autosize", "on");
if (input.initialUrl) {
(webview as BrowserWebviewElement).src = input.initialUrl;
}
registerBrowserWhenAttached(webview as BrowserWebviewElement, input, browser);
}
export function ensureResidentBrowserWebview(input: {
browserId: string;
workspaceId: string;
url: string;
profileHost?: BrowserWebviewProfileHost;
}): HTMLElement | null {
const browserId = trimNonEmpty(input.browserId);
if (!browserId) {
return null;
}
const ownerDocument = readDocument();
if (!ownerDocument) {
return null;
}
const resident = residentWebviewsByBrowserId.get(browserId) ?? null;
if (resident?.isConnected) {
releaseResidentBrowserWebview(browserId, resident);
return resident;
}
const existing = findBrowserWebview(browserId, ownerDocument);
if (existing) {
if (existing.parentElement?.id === RESIDENT_BROWSER_HOST_ID) {
releaseResidentBrowserWebview(browserId, existing);
}
return existing;
}
const webview = ownerDocument.createElement("webview") as BrowserWebviewElement;
prepareBrowserWebview(webview, {
browserId,
workspaceId: input.workspaceId,
initialUrl: input.url,
profileHost: input.profileHost,
});
releaseResidentBrowserWebview(browserId, webview);
return webview;
}
export function getResidentBrowserWebview(browserId: string): HTMLElement | null {
const normalizedBrowserId = trimNonEmpty(browserId);
if (!normalizedBrowserId) {
return null;
}
const resident = residentWebviewsByBrowserId.get(normalizedBrowserId) ?? null;
if (resident?.isConnected) {
return resident;
}
const ownerDocument = readDocument();
return ownerDocument ? findBrowserWebview(normalizedBrowserId, ownerDocument) : null;
}
export function takeResidentBrowserWebview(browserId: string): HTMLElement | null {
const normalizedBrowserId = trimNonEmpty(browserId);
if (!normalizedBrowserId) {
return null;
}
const webview = residentWebviewsByBrowserId.get(normalizedBrowserId) ?? null;
if (!webview) {
return null;
}
residentWebviewsByBrowserId.delete(normalizedBrowserId);
clearResidentWebviewParkingStyle(webview);
return webview;
}
export function releaseResidentBrowserWebview(browserId: string, webview: HTMLElement): void {
const normalizedBrowserId = trimNonEmpty(browserId);
if (!normalizedBrowserId) {
webview.remove();
return;
}
const ownerDocument = readDocument();
if (!ownerDocument) {
return;
}
residentWebviewsByBrowserId.set(normalizedBrowserId, webview);
applyResidentWebviewStyle(webview, normalizedBrowserId);
getResidentBrowserHost(ownerDocument).appendChild(webview);
}
export function resizeResidentBrowserWebview(input: {
browserId: string;
width: number;
height: number;
}): { width: number; height: number } | null {
const normalizedBrowserId = trimNonEmpty(input.browserId);
if (!normalizedBrowserId) {
return null;
}
const width = Math.max(1, Math.round(input.width));
const height = Math.max(1, Math.round(input.height));
residentWebviewSizesByBrowserId.set(normalizedBrowserId, { width, height });
const ownerDocument = readDocument();
const webview = ownerDocument ? findBrowserWebview(normalizedBrowserId, ownerDocument) : null;
if (webview) {
webview.style.width = `${width}px`;
webview.style.height = `${height}px`;
}
return { width, height };
}
export function removeResidentBrowserWebview(browserId: string): void {
const normalizedBrowserId = trimNonEmpty(browserId);
if (!normalizedBrowserId) {
return;
}
const resident = residentWebviewsByBrowserId.get(normalizedBrowserId) ?? null;
residentWebviewsByBrowserId.delete(normalizedBrowserId);
residentWebviewSizesByBrowserId.delete(normalizedBrowserId);
resident?.remove();
}
export function clearResidentBrowserWebviewsForTests(): void {
for (const webview of residentWebviewsByBrowserId.values()) {
webview.remove();
}
residentWebviewsByBrowserId.clear();
residentWebviewSizesByBrowserId.clear();
readDocument()?.getElementById(RESIDENT_BROWSER_HOST_ID)?.remove();
}