diff --git a/packages/dashboard/app/components/ReliabilityView.css b/packages/dashboard/app/components/ReliabilityView.css
index 5403ac7555..6d26d81d2d 100644
--- a/packages/dashboard/app/components/ReliabilityView.css
+++ b/packages/dashboard/app/components/ReliabilityView.css
@@ -1,9 +1,11 @@
.reliability-view {
display: flex;
+ flex: 1 1 auto;
flex-direction: column;
gap: var(--space-lg);
height: 100%;
min-height: 0;
+ min-width: 0;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
@@ -17,20 +19,24 @@
.reliability-loading {
display: flex;
+ flex: 1 1 auto;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--space-md);
+ min-width: 0;
padding: var(--space-2xl);
color: var(--text-muted);
}
.reliability-error {
display: flex;
+ flex: 1 1 auto;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--space-md);
+ min-width: 0;
padding: var(--space-2xl);
text-align: center;
}
diff --git a/packages/dashboard/app/components/__tests__/ReliabilityView.test.tsx b/packages/dashboard/app/components/__tests__/ReliabilityView.test.tsx
index 8d17c0dd21..9a1b981b3b 100644
--- a/packages/dashboard/app/components/__tests__/ReliabilityView.test.tsx
+++ b/packages/dashboard/app/components/__tests__/ReliabilityView.test.tsx
@@ -32,6 +32,27 @@ const baseResponse = {
mergeAttempts: { mean: 1.2, max: 2, histogram: { "1": 1 } },
};
+function renderInProjectContent() {
+ return render(
+
+
+
,
+ );
+}
+
+function setViewportWidth(width: number) {
+ Object.defineProperty(window, "innerWidth", { configurable: true, value: width });
+ window.dispatchEvent(new Event("resize"));
+}
+
+function expectFlexFill(element: HTMLElement) {
+ const computed = getComputedStyle(element);
+ expect(computed.flexGrow).toBe("1");
+ expect(computed.flexShrink).toBe("1");
+ expect(computed.flexBasis).toBe("auto");
+ expect(computed.minWidth).toBe("0px");
+}
+
describe("ReliabilityView", () => {
afterEach(() => {
vi.useRealTimers();
@@ -58,6 +79,44 @@ describe("ReliabilityView", () => {
expect(screen.queryByRole("heading", { name: "Reliability" })).not.toBeInTheDocument();
});
+ it.each([
+ ["desktop", 1024],
+ ["mobile", 375],
+ ])("fills flex parent width in %s loading state", (_label, width) => {
+ setViewportWidth(width);
+ vi.spyOn(globalThis, "fetch").mockReturnValue(new Promise(() => {}));
+
+ renderInProjectContent();
+
+ expectFlexFill(screen.getByTestId("reliability-loading"));
+ });
+
+ it.each([
+ ["desktop", 1024],
+ ["mobile", 375],
+ ])("fills flex parent width in %s populated state", async (_label, width) => {
+ setViewportWidth(width);
+ vi.spyOn(globalThis, "fetch").mockResolvedValue({ ok: true, json: async () => baseResponse } as Response);
+
+ const { container } = renderInProjectContent();
+
+ await waitFor(() => expect(container.querySelector(".reliability-view")).not.toBeNull());
+ expectFlexFill(container.querySelector(".reliability-view") as HTMLElement);
+ });
+
+ it.each([
+ ["desktop", 1024],
+ ["mobile", 375],
+ ])("fills flex parent width in %s error state", async (_label, width) => {
+ setViewportWidth(width);
+ vi.spyOn(globalThis, "fetch").mockRejectedValue(new Error("Network unavailable"));
+
+ renderInProjectContent();
+
+ await waitFor(() => expect(screen.getByTestId("reliability-error")).toBeInTheDocument());
+ expectFlexFill(screen.getByTestId("reliability-error"));
+ });
+
it("shows data after successful load even if loading refresh is pending", async () => {
vi.useFakeTimers();
const fetchSpy = vi.spyOn(globalThis, "fetch")