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:
+1
-1
@@ -3,7 +3,7 @@ import type { SessionInboundMessage, SessionOutboundMessage } from "@getpaseo/pr
|
||||
import { createJSONStorage, type StateStorage } from "zustand/middleware";
|
||||
import { mountBrowserAutomationHandler } from "./handler";
|
||||
import type { DesktopHostBridge } from "@/desktop/host";
|
||||
import { useBrowserStore } from "@/stores/browser-store";
|
||||
import { useBrowserStore } from "@/desktop/browser/store";
|
||||
import { useWorkspaceLayoutStore } from "@/stores/workspace-layout-store";
|
||||
import { buildWorkspaceTabPersistenceKey } from "@/workspace-tabs/model";
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ import {
|
||||
ensureResidentBrowserWebview as ensureResidentBrowserWebviewDefault,
|
||||
removeResidentBrowserWebview,
|
||||
resizeResidentBrowserWebview,
|
||||
} from "@/components/browser-webview-resident";
|
||||
import { createWorkspaceBrowser, getBrowserRecord, useBrowserStore } from "@/stores/browser-store";
|
||||
} from "@/desktop/browser/resident-webviews";
|
||||
import { createWorkspaceBrowser, getBrowserRecord, useBrowserStore } from "@/desktop/browser/store";
|
||||
import { collectAllTabs, useWorkspaceLayoutStore } from "@/stores/workspace-layout-store";
|
||||
import { buildWorkspaceTabPersistenceKey } from "@/workspace-tabs/model";
|
||||
|
||||
+2
-2
@@ -49,12 +49,12 @@ import {
|
||||
isElectronRuntime,
|
||||
type DesktopBrowserShortcutEvent,
|
||||
} from "@/desktop/host";
|
||||
import { useBrowserStore, normalizeWorkspaceBrowserUrl } from "@/stores/browser-store";
|
||||
import { useBrowserStore, normalizeWorkspaceBrowserUrl } from "@/desktop/browser/store";
|
||||
import {
|
||||
prepareBrowserWebview,
|
||||
releaseResidentBrowserWebview,
|
||||
takeResidentBrowserWebview,
|
||||
} from "./browser-webview-resident";
|
||||
} from "../resident-webviews";
|
||||
|
||||
type ElectronWebview = HTMLElement & {
|
||||
canGoBack?: () => boolean;
|
||||
+2
-2
@@ -2,10 +2,10 @@ import { useMemo } from "react";
|
||||
import { Image } from "react-native";
|
||||
import { Globe } from "lucide-react-native";
|
||||
import invariant from "tiny-invariant";
|
||||
import { BrowserPane } from "@/components/browser-pane";
|
||||
import { BrowserPane } from "@/desktop/browser/pane";
|
||||
import { usePaneContext, usePaneFocus } from "@/panels/pane-context";
|
||||
import type { PanelDescriptor, PanelIconProps, PanelRegistration } from "@/panels/panel-registry";
|
||||
import { useBrowserStore } from "@/stores/browser-store";
|
||||
import { useBrowserStore } from "@/desktop/browser/store";
|
||||
import { useWorkspaceDirectory } from "@/stores/session-store-hooks";
|
||||
|
||||
function getBrowserLabel(input: { title: string; url: string }): string {
|
||||
+2
-2
@@ -8,11 +8,11 @@ import {
|
||||
releaseResidentBrowserWebview,
|
||||
removeResidentBrowserWebview,
|
||||
takeResidentBrowserWebview,
|
||||
} from "./browser-webview-resident";
|
||||
} from "./resident-webviews";
|
||||
import {
|
||||
setCommandCenterFocusRestoreElement,
|
||||
takeCommandCenterFocusRestoreElement,
|
||||
} from "../utils/command-center-focus-restore";
|
||||
} from "../../utils/command-center-focus-restore";
|
||||
|
||||
const RESIDENT_HOST_ID = "paseo-browser-resident-webviews";
|
||||
const attachedBrowsers: Array<{
|
||||
+1
-1
@@ -5,7 +5,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { useToast } from "@/contexts/toast-context";
|
||||
import { getDesktopHost } from "@/desktop/host";
|
||||
import { SettingsSection } from "@/screens/settings/settings-section";
|
||||
import { useBrowserStore } from "@/stores/browser-store";
|
||||
import { useBrowserStore } from "@/desktop/browser/store";
|
||||
import { settingsStyles } from "@/styles/settings";
|
||||
import { confirmDialog } from "@/utils/confirm-dialog";
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ import {
|
||||
buildBrowserKeyboardPolicy,
|
||||
parseBrowserShortcutInput,
|
||||
shouldPublishBrowserShortcutPolicy,
|
||||
} from "./browser-shortcuts";
|
||||
import { buildEffectiveBindings, resolveKeyboardShortcut } from "./keyboard-shortcuts";
|
||||
} from "./shortcuts";
|
||||
import { buildEffectiveBindings, resolveKeyboardShortcut } from "../../keyboard/keyboard-shortcuts";
|
||||
|
||||
describe("buildBrowserKeyboardPolicy", () => {
|
||||
it("publishes only chord starts while no browser chord is pending", () => {
|
||||
+2
-2
@@ -3,8 +3,8 @@ import {
|
||||
matchesKeyboardShortcutContext,
|
||||
type KeyboardShortcutInput,
|
||||
type ParsedShortcutBinding,
|
||||
} from "./keyboard-shortcuts";
|
||||
import type { KeyCombo } from "./shortcut-string";
|
||||
} from "../../keyboard/keyboard-shortcuts";
|
||||
import type { KeyCombo } from "../../keyboard/shortcut-string";
|
||||
|
||||
export interface BrowserShortcutPrefix {
|
||||
alt: boolean;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Platform } from "react-native";
|
||||
import { getElectronHost } from "@/desktop/electron/host";
|
||||
import type { BrowserKeyboardPolicy } from "@/keyboard/browser-shortcuts";
|
||||
import type { BrowserKeyboardPolicy } from "@/desktop/browser/shortcuts";
|
||||
import type { SessionInboundMessage, SessionOutboundMessage } from "@getpaseo/protocol/messages";
|
||||
|
||||
type BrowserAutomationExecuteRequest = Extract<
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { createServer, type Server } from "node:http";
|
||||
import { afterEach, expect, test } from "vitest";
|
||||
|
||||
import { waitForMetro } from "../e2e/global-setup";
|
||||
import { waitForMetro, warmMetro } from "../e2e/support/global-setup";
|
||||
|
||||
class MetroPort {
|
||||
private response = { status: 500, body: "fallback" };
|
||||
private readonly responses = new Map<string, { status: number; body: string }>();
|
||||
readonly requests: string[] = [];
|
||||
|
||||
private constructor(
|
||||
readonly port: number,
|
||||
@@ -13,9 +14,12 @@ class MetroPort {
|
||||
|
||||
static async listen(): Promise<MetroPort> {
|
||||
let endpoint!: MetroPort;
|
||||
const server = createServer((_request, response) => {
|
||||
response.writeHead(endpoint.response.status, { "content-type": "text/plain" });
|
||||
response.end(endpoint.response.body);
|
||||
const server = createServer((request, response) => {
|
||||
const pathname = new URL(request.url ?? "/", "http://localhost").pathname;
|
||||
endpoint.requests.push(pathname);
|
||||
const served = endpoint.responses.get(pathname) ?? { status: 500, body: "fallback" };
|
||||
response.writeHead(served.status, { "content-type": "text/plain" });
|
||||
response.end(served.body);
|
||||
});
|
||||
await new Promise<void>((resolve) => server.listen(0, "127.0.0.1", resolve));
|
||||
const address = server.address();
|
||||
@@ -28,7 +32,15 @@ class MetroPort {
|
||||
}
|
||||
|
||||
serveMetro(): void {
|
||||
this.response = { status: 200, body: "packager-status:running" };
|
||||
this.responses.set("/status", { status: 200, body: "packager-status:running" });
|
||||
}
|
||||
|
||||
serveWarmableDocument(): void {
|
||||
this.responses.set("/", {
|
||||
status: 200,
|
||||
body: '<html><script src="/index.bundle?platform=web"></script></html>',
|
||||
});
|
||||
this.responses.set("/index.bundle", { status: 200, body: "compiled bundle" });
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
@@ -63,3 +75,12 @@ test("Metro readiness rejects another HTTP listener on the selected port", async
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
test("Metro warmup compiles the document's same-origin scripts before tests start", async () => {
|
||||
endpoint = await MetroPort.listen();
|
||||
endpoint.serveWarmableDocument();
|
||||
|
||||
await warmMetro(endpoint.port);
|
||||
|
||||
expect(endpoint.requests).toEqual(["/", "/index.bundle"]);
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ import { usePathname, useRouter } from "expo-router";
|
||||
import { getIsElectronRuntime } from "@/constants/layout";
|
||||
import { useKeyboardShortcutsStore } from "@/stores/keyboard-shortcuts-store";
|
||||
import { setCommandCenterFocusRestoreElement } from "@/utils/command-center-focus-restore";
|
||||
import { getResidentBrowserWebview } from "@/components/browser-webview-resident";
|
||||
import { getResidentBrowserWebview } from "@/desktop/browser/resident-webviews";
|
||||
import { navigateToWorkspace } from "@/stores/navigation-active-workspace-store";
|
||||
import { keyboardActionDispatcher } from "@/keyboard/keyboard-action-dispatcher";
|
||||
import {
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
buildBrowserKeyboardPolicy,
|
||||
parseBrowserShortcutInput,
|
||||
shouldPublishBrowserShortcutPolicy,
|
||||
} from "@/keyboard/browser-shortcuts";
|
||||
} from "@/desktop/browser/shortcuts";
|
||||
import type { KeyboardFocusScope, KeyboardShortcutPayload } from "@/keyboard/actions";
|
||||
import {
|
||||
routeKeyboardShortcut,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { agentPanelRegistration } from "@/panels/agent-panel";
|
||||
import { browserPanelRegistration } from "@/panels/browser-panel";
|
||||
import { browserPanelRegistration } from "@/desktop/browser/panel";
|
||||
import { commitDiffPanelRegistration, workingDiffPanelRegistration } from "@/panels/diff-panel";
|
||||
import { draftPanelRegistration } from "@/panels/draft-panel";
|
||||
import { filePanelRegistration } from "@/panels/file-panel";
|
||||
|
||||
@@ -47,7 +47,7 @@ import {
|
||||
invalidateServerDataQueriesAfterReconnect,
|
||||
mountServerDataPushRouter,
|
||||
} from "@/data/push-router";
|
||||
import { mountBrowserAutomationDaemonClientHandler } from "@/browser-automation/handler";
|
||||
import { mountBrowserAutomationDaemonClientHandler } from "@/desktop/browser/automation/handler";
|
||||
import { schedulesQueryBaseKey } from "@/schedules/aggregated-schedules";
|
||||
import { dispatchComposerAgentMessage, sendQueuedComposerMessageNow } from "@/composer/actions";
|
||||
import { createMessageSubmissionWriter } from "@/composer/submission/writer";
|
||||
|
||||
@@ -77,7 +77,7 @@ import { CommunityLinks } from "@/components/community-links";
|
||||
import { SegmentedControl } from "@/components/ui/segmented-control";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem } from "@/components/ui/dropdown-menu";
|
||||
import { DesktopPermissionsSection } from "@/desktop/components/desktop-permissions-section";
|
||||
import { BrowserDataSection } from "@/desktop/components/browser-data-section";
|
||||
import { BrowserDataSection } from "@/desktop/browser/settings/browser-data-section";
|
||||
import { IntegrationsSection } from "@/desktop/components/integrations-section";
|
||||
import { isElectronRuntime } from "@/desktop/host";
|
||||
import { useDesktopAppUpdater } from "@/desktop/updates/use-desktop-app-updater";
|
||||
|
||||
@@ -110,8 +110,8 @@ import type { CheckoutStatusPayload } from "@/git/use-status-query";
|
||||
import { confirmDialog } from "@/utils/confirm-dialog";
|
||||
import { useArchiveAgent } from "@/hooks/use-archive-agent";
|
||||
import { useStableEvent } from "@/hooks/use-stable-event";
|
||||
import { removeResidentBrowserWebview } from "@/components/browser-webview-resident";
|
||||
import { createWorkspaceBrowser, useBrowserStore } from "@/stores/browser-store";
|
||||
import { removeResidentBrowserWebview } from "@/desktop/browser/resident-webviews";
|
||||
import { createWorkspaceBrowser, useBrowserStore } from "@/desktop/browser/store";
|
||||
import { getDesktopHost } from "@/desktop/host";
|
||||
import { buildProviderCommand } from "@/utils/provider-command-templates";
|
||||
import { generateDraftId } from "@/stores/draft-keys";
|
||||
@@ -135,7 +135,7 @@ import {
|
||||
type WorkspaceTabMenuEntry,
|
||||
type WorkspaceTabMenuLabels,
|
||||
} from "@/screens/workspace/workspace-tab-menu";
|
||||
import { useDesktopBrowserNewTabRequests } from "@/browser/new-tab-requests";
|
||||
import { useDesktopBrowserNewTabRequests } from "@/desktop/browser/new-tab-requests";
|
||||
import type { WorkspaceTabDescriptor } from "@/screens/workspace/workspace-tabs-types";
|
||||
import {
|
||||
resolveWorkspaceHeaderRenderState,
|
||||
|
||||
Reference in New Issue
Block a user