From 18b1c88f2cf19c602b89639d19e2984f12b2e688 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Thu, 27 Jun 2024 09:28:43 +0200 Subject: [PATCH 1/4] Reduce API polling rate to 30s, use health endpoint and use browser online status API --- src/Panel.tsx | 18 +++++++++++++++--- src/preset.ts | 14 ++++---------- src/screens/NoNetwork/NoNetwork.stories.tsx | 7 +++++++ src/screens/NoNetwork/NoNetwork.tsx | 6 ++++-- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/Panel.tsx b/src/Panel.tsx index d972c750..3adfd7a4 100644 --- a/src/Panel.tsx +++ b/src/Panel.tsx @@ -1,6 +1,6 @@ import type { API } from "@storybook/manager-api"; import { useChannel, useStorybookState } from "@storybook/manager-api"; -import React, { useCallback } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import { AuthProvider } from "./AuthContext"; import { Spinner } from "./components/design-system"; @@ -51,6 +51,18 @@ export const Panel = ({ active, api }: PanelProps) => { ); const { storyId } = useStorybookState(); + const [isOnline, setOnline] = useState(window.navigator.onLine); + useEffect(() => { + const online = () => setOnline(true); + const offline = () => setOnline(false); + window.addEventListener("online", online); + window.addEventListener("offline", offline); + return () => { + window.removeEventListener("online", online); + window.removeEventListener("offline", offline); + }; + }, []); + const [apiInfo] = useSharedState(API_INFO); const [gitInfo] = useSharedState(GIT_INFO); const [gitInfoError] = useSharedState(GIT_INFO_ERROR); @@ -114,8 +126,8 @@ export const Panel = ({ active, api }: PanelProps) => { return withProviders(); } - if (apiInfo?.connected === false) { - return withProviders(); + if (!isOnline || apiInfo?.connected === false) { + return withProviders(); } // Render the Authentication flow if the user is not signed in. diff --git a/src/preset.ts b/src/preset.ts index f74c8f3a..a920b6d2 100644 --- a/src/preset.ts +++ b/src/preset.ts @@ -12,7 +12,6 @@ import { type Configuration, getConfiguration, getGitInfo, type GitInfo } from " import { ADDON_ID, API_INFO, - CHROMATIC_API_URL, CHROMATIC_BASE_URL, CONFIG_INFO, GIT_INFO, @@ -123,14 +122,9 @@ const observeAPIInfo = (interval: number, callback: (apiInfo: APIInfoPayload) => callback({ aborted: true, connected: false }); return; } - const ok = await fetch(CHROMATIC_API_URL, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ query: `{ viewer { id } }` }), - }).then( - (res) => res.ok, - () => false - ); + const ok = await fetch("https://index.chromatic.com/healthz") + .then((res) => res.json().then(({ message }) => message === "OK")) + .catch(() => false); if (ok || attempt > 1) { callback({ aborted: false, connected: ok }); } @@ -265,7 +259,7 @@ async function serverChannel(channel: Channel, options: Options & { configFile?: const gitInfoState = SharedState.subscribe(GIT_INFO, channel); const gitInfoError = SharedState.subscribe(GIT_INFO_ERROR, channel); - let apiInfoObserver = observeAPIInfo(5000, (info: APIInfoPayload) => { + let apiInfoObserver = observeAPIInfo(30000, (info: APIInfoPayload) => { apiInfoState.value = info; }); diff --git a/src/screens/NoNetwork/NoNetwork.stories.tsx b/src/screens/NoNetwork/NoNetwork.stories.tsx index 3fd11203..aa81aa04 100644 --- a/src/screens/NoNetwork/NoNetwork.stories.tsx +++ b/src/screens/NoNetwork/NoNetwork.stories.tsx @@ -6,6 +6,7 @@ const meta = { component: NoNetwork, args: { aborted: false, + online: true, }, } satisfies Meta; @@ -18,3 +19,9 @@ export const Aborted = { aborted: true, }, } satisfies StoryObj; + +export const Offline = { + args: { + online: false, + }, +} satisfies StoryObj; diff --git a/src/screens/NoNetwork/NoNetwork.tsx b/src/screens/NoNetwork/NoNetwork.tsx index 38fcca15..01650d5b 100644 --- a/src/screens/NoNetwork/NoNetwork.tsx +++ b/src/screens/NoNetwork/NoNetwork.tsx @@ -17,7 +17,7 @@ const SpinIcon = styled(SyncIcon)({ animation: `${rotate360} 1s linear infinite`, }); -export const NoNetwork = ({ aborted }: { aborted: boolean }) => { +export const NoNetwork = ({ aborted, online }: { aborted: boolean; online: boolean }) => { const [retried, setRetried] = useState(false); const emit = useChannel({}); @@ -37,7 +37,9 @@ export const NoNetwork = ({ aborted }: { aborted: boolean }) => {
Can't connect to Chromatic - Double check your internet connection and firewall settings. + {online + ? "We're having trouble connecting to the Chromatic API." + : "You're offline. Double check your internet connection."}
{aborted ? ( From bfae14f0f359ebd76ffe42e2b2527e3e5d0752bb Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Thu, 27 Jun 2024 22:11:00 +0200 Subject: [PATCH 2/4] Remove health check polling and move online status check to sidebar --- src/Panel.tsx | 10 ++--- src/SidebarTop.tsx | 19 ++++++-- src/constants.ts | 3 +- src/preset.ts | 40 ----------------- src/screens/NoNetwork/NoNetwork.stories.tsx | 12 +---- src/screens/NoNetwork/NoNetwork.tsx | 50 +++++---------------- src/types.ts | 4 -- 7 files changed, 32 insertions(+), 106 deletions(-) diff --git a/src/Panel.tsx b/src/Panel.tsx index 3adfd7a4..0a4b10e4 100644 --- a/src/Panel.tsx +++ b/src/Panel.tsx @@ -6,9 +6,9 @@ import { AuthProvider } from "./AuthContext"; import { Spinner } from "./components/design-system"; import { ADDON_ID, - API_INFO, GIT_INFO, GIT_INFO_ERROR, + IS_OFFLINE, IS_OUTDATED, LOCAL_BUILD_PROGRESS, PANEL_ID, @@ -27,7 +27,7 @@ import { Uninstalled } from "./screens/Uninstalled/Uninstalled"; import { ControlsProvider } from "./screens/VisualTests/ControlsContext"; import { RunBuildProvider } from "./screens/VisualTests/RunBuildContext"; import { VisualTests } from "./screens/VisualTests/VisualTests"; -import { APIInfoPayload, GitInfoPayload, LocalBuildProgress, UpdateStatusFunction } from "./types"; +import { GitInfoPayload, LocalBuildProgress, UpdateStatusFunction } from "./types"; import { client, Provider, useAccessToken } from "./utils/graphQLClient"; import { TelemetryProvider } from "./utils/TelemetryContext"; import { useBuildEvents } from "./utils/useBuildEvents"; @@ -63,9 +63,9 @@ export const Panel = ({ active, api }: PanelProps) => { }; }, []); - const [apiInfo] = useSharedState(API_INFO); const [gitInfo] = useSharedState(GIT_INFO); const [gitInfoError] = useSharedState(GIT_INFO_ERROR); + const [isOffline] = useSharedState(IS_OFFLINE); const [isOutdated] = useSharedState(IS_OUTDATED); const [localBuildProgress, setLocalBuildProgress] = useSharedState(LOCAL_BUILD_PROGRESS); @@ -126,8 +126,8 @@ export const Panel = ({ active, api }: PanelProps) => { return withProviders(); } - if (!isOnline || apiInfo?.connected === false) { - return withProviders(); + if (isOffline) { + return withProviders(); } // Render the Authentication flow if the user is not signed in. diff --git a/src/SidebarTop.tsx b/src/SidebarTop.tsx index 98a150d1..2ca4c9f4 100644 --- a/src/SidebarTop.tsx +++ b/src/SidebarTop.tsx @@ -7,14 +7,14 @@ import React, { useCallback, useContext, useEffect, useRef } from "react"; import { SidebarTopButton } from "./components/SidebarTopButton"; import { ADDON_ID, - API_INFO, CONFIG_INFO, GIT_INFO_ERROR, + IS_OFFLINE, IS_OUTDATED, LOCAL_BUILD_PROGRESS, PANEL_ID, } from "./constants"; -import { APIInfoPayload, ConfigInfoPayload, LocalBuildProgress } from "./types"; +import { ConfigInfoPayload, LocalBuildProgress } from "./types"; import { useAccessToken } from "./utils/graphQLClient"; import { TelemetryContext } from "./utils/TelemetryContext"; import { useBuildEvents } from "./utils/useBuildEvents"; @@ -33,10 +33,10 @@ export const SidebarTop = ({ api }: SidebarTopProps) => { const [accessToken] = useAccessToken(); const isLoggedIn = !!accessToken; + const [isOffline, setOffline] = useSharedState(IS_OFFLINE); const [isOutdated] = useSharedState(IS_OUTDATED); const [localBuildProgress] = useSharedState(LOCAL_BUILD_PROGRESS); - const [apiInfo] = useSharedState(API_INFO); const [configInfo] = useSharedState(CONFIG_INFO); const hasConfigProblem = Object.keys(configInfo?.problems || {}).length > 0; @@ -74,6 +74,17 @@ export const SidebarTop = ({ api }: SidebarTopProps) => { [openVisualTestsPanel] ); + useEffect(() => { + const offline = () => setOffline(true); + const online = () => setOffline(false); + window.addEventListener("offline", offline); + window.addEventListener("online", online); + return () => { + window.removeEventListener("offline", offline); + window.removeEventListener("online", online); + }; + }, [setOffline]); + useEffect(() => { if (localBuildProgress?.currentStep === lastStep.current) return; lastStep.current = localBuildProgress?.currentStep; @@ -179,11 +190,11 @@ export const SidebarTop = ({ api }: SidebarTopProps) => { }); let warning: string | undefined; - if (apiInfo?.connected === false) warning = "Visual tests locked while waiting for network."; if (!projectId) warning = "Visual tests locked until a project is selected."; if (!isLoggedIn) warning = "Visual tests locked until you are logged in."; if (gitInfoError) warning = "Visual tests locked due to Git synchronization problem."; if (hasConfigProblem) warning = "Visual tests locked due to configuration problem."; + if (isOffline) warning = "Visual tests locked while offline."; const clickWarning = useCallback( () => openVisualTestsPanel(warning), diff --git a/src/constants.ts b/src/constants.ts index bcce5d86..a9056115 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -12,12 +12,12 @@ export const SIDEBAR_TOP_ID = `${ADDON_ID}/sidebarTop`; export const SIDEBAR_BOTTOM_ID = `${ADDON_ID}/sidebarBottom`; export const ACCESS_TOKEN_KEY = `${ADDON_ID}/access-token/${CHROMATIC_BASE_URL}`; export const DEV_BUILD_ID_KEY = `${ADDON_ID}/dev-build-id`; -export const API_INFO = `${ADDON_ID}/apiInfo`; export const CONFIG_INFO = `${ADDON_ID}/configInfo`; export const CONFIG_INFO_DISMISSED = `${ADDON_ID}/configInfoDismissed`; export const GIT_INFO = `${ADDON_ID}/gitInfo`; export const GIT_INFO_ERROR = `${ADDON_ID}/gitInfoError`; export const PROJECT_INFO = `${ADDON_ID}/projectInfo`; +export const IS_OFFLINE = `${ADDON_ID}/isOffline`; export const IS_OUTDATED = `${ADDON_ID}/isOutdated`; export const START_BUILD = `${ADDON_ID}/startBuild`; export const STOP_BUILD = `${ADDON_ID}/stopBuild`; @@ -27,7 +27,6 @@ export const SELECTED_BROWSER_ID = `${ADDON_ID}/selectedBrowserId`; export const TELEMETRY = `${ADDON_ID}/telemetry`; export const ENABLE_FILTER = `${ADDON_ID}/enableFilter`; export const REMOVE_ADDON = `${ADDON_ID}/removeAddon`; -export const RETRY_CONNECTION = `${ADDON_ID}/retryConnection`; export const CONFIG_OVERRIDES = { // Local changes should never be auto-accepted diff --git a/src/preset.ts b/src/preset.ts index a920b6d2..8c9b7360 100644 --- a/src/preset.ts +++ b/src/preset.ts @@ -11,7 +11,6 @@ import { type Configuration, getConfiguration, getGitInfo, type GitInfo } from " import { ADDON_ID, - API_INFO, CHROMATIC_BASE_URL, CONFIG_INFO, GIT_INFO, @@ -20,14 +19,12 @@ import { PACKAGE_NAME, PROJECT_INFO, REMOVE_ADDON, - RETRY_CONNECTION, START_BUILD, STOP_BUILD, TELEMETRY, } from "./constants"; import { runChromaticBuild, stopChromaticBuild } from "./runChromaticBuild"; import { - APIInfoPayload, ConfigInfoPayload, ConfigurationUpdate, GitInfoPayload, @@ -111,30 +108,6 @@ const getConfigInfo = async ( }; }; -// Polls for a connection to the Chromatic API. -// Uses a recursive setTimeout instead of setInterval to avoid overlapping async calls. -// Two consecutive failures are needed before considering the connection as lost. -// Retries with an increasing delay after the first failure and aborts after 10 attempts. -const observeAPIInfo = (interval: number, callback: (apiInfo: APIInfoPayload) => void) => { - let timer: NodeJS.Timeout | undefined; - const act = async (attempt = 1) => { - if (attempt > 10) { - callback({ aborted: true, connected: false }); - return; - } - const ok = await fetch("https://index.chromatic.com/healthz") - .then((res) => res.json().then(({ message }) => message === "OK")) - .catch(() => false); - if (ok || attempt > 1) { - callback({ aborted: false, connected: ok }); - } - timer = ok ? setTimeout(act, interval) : setTimeout(act, attempt * 1000, attempt + 1); - }; - act(); - - return { cancel: () => clearTimeout(timer) }; -}; - // Polls for changes to the Git state and invokes the callback when it changes. // Uses a recursive setTimeout instead of setInterval to avoid overlapping async calls. const observeGitInfo = ( @@ -254,15 +227,10 @@ async function serverChannel(channel: Channel, options: Options & { configFile?: telemetry("addon-visual-tests" as any, { ...event, addonVersion: await getAddonVersion() }); }); - const apiInfoState = SharedState.subscribe(API_INFO, channel); const configInfoState = SharedState.subscribe(CONFIG_INFO, channel); const gitInfoState = SharedState.subscribe(GIT_INFO, channel); const gitInfoError = SharedState.subscribe(GIT_INFO_ERROR, channel); - let apiInfoObserver = observeAPIInfo(30000, (info: APIInfoPayload) => { - apiInfoState.value = info; - }); - const gitInfoObserver = observeGitInfo( 5000, (info) => { @@ -283,17 +251,9 @@ async function serverChannel(channel: Channel, options: Options & { configFile?: channel.on(REMOVE_ADDON, () => { apiPromise.then((api) => api.removeAddon(PACKAGE_NAME)).catch((e) => console.error(e)); - apiInfoObserver.cancel(); gitInfoObserver.cancel(); }); - channel.on(RETRY_CONNECTION, () => { - apiInfoObserver.cancel(); - apiInfoObserver = observeAPIInfo(5000, (info: APIInfoPayload) => { - apiInfoState.value = info; - }); - }); - return channel; } diff --git a/src/screens/NoNetwork/NoNetwork.stories.tsx b/src/screens/NoNetwork/NoNetwork.stories.tsx index aa81aa04..2f109dd8 100644 --- a/src/screens/NoNetwork/NoNetwork.stories.tsx +++ b/src/screens/NoNetwork/NoNetwork.stories.tsx @@ -4,24 +4,14 @@ import { NoNetwork } from "./NoNetwork"; const meta = { component: NoNetwork, - args: { - aborted: false, - online: true, - }, } satisfies Meta; export default meta; export const Default = {} satisfies StoryObj; -export const Aborted = { - args: { - aborted: true, - }, -} satisfies StoryObj; - export const Offline = { args: { - online: false, + offline: true, }, } satisfies StoryObj; diff --git a/src/screens/NoNetwork/NoNetwork.tsx b/src/screens/NoNetwork/NoNetwork.tsx index 01650d5b..b9502dfc 100644 --- a/src/screens/NoNetwork/NoNetwork.tsx +++ b/src/screens/NoNetwork/NoNetwork.tsx @@ -1,35 +1,13 @@ -import { SyncIcon } from "@storybook/icons"; -import { useChannel } from "@storybook/manager-api"; -import { styled } from "@storybook/theming"; -import React, { useEffect, useState } from "react"; +import React from "react"; -import { Button } from "../../components/Button"; import { Container } from "../../components/Container"; import { Link } from "../../components/design-system"; -import { rotate360 } from "../../components/design-system/shared/animation"; import { Heading } from "../../components/Heading"; import { Screen } from "../../components/Screen"; import { Stack } from "../../components/Stack"; import { Text } from "../../components/Text"; -import { RETRY_CONNECTION } from "../../constants"; - -const SpinIcon = styled(SyncIcon)({ - animation: `${rotate360} 1s linear infinite`, -}); - -export const NoNetwork = ({ aborted, online }: { aborted: boolean; online: boolean }) => { - const [retried, setRetried] = useState(false); - const emit = useChannel({}); - - const retry = () => { - setRetried(true); - emit(RETRY_CONNECTION); - }; - - useEffect(() => { - setRetried(false); - }, [aborted]); +export const NoNetwork = ({ offline = false }: { offline?: boolean }) => { return ( @@ -37,25 +15,17 @@ export const NoNetwork = ({ aborted, online }: { aborted: boolean; online: boole
Can't connect to Chromatic - {online - ? "We're having trouble connecting to the Chromatic API." - : "You're offline. Double check your internet connection."} + {offline + ? "You're offline. Double check your internet connection." + : "We're having trouble connecting to the Chromatic API."}
- {aborted ? ( - - ) : ( - + + {!offline && ( + + Chromatic API status + )} - - Chromatic API status -
diff --git a/src/types.ts b/src/types.ts index 2bd6f9b1..eb5b8f54 100644 --- a/src/types.ts +++ b/src/types.ts @@ -26,10 +26,6 @@ export type ConfigurationUpdate = { [Property in keyof Configuration]: Configuration[Property] | null; }; -export type APIInfoPayload = { - aborted: boolean; - connected: boolean; -}; export type ConfigInfoPayload = { configuration: Awaited>; problems?: ConfigurationUpdate; From 340a4fd9d184bdfc798b63efd8e56af096635b4d Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Tue, 28 May 2024 15:24:04 +0200 Subject: [PATCH 3/4] Add stories for SidebarBottom and move into components folder --- src/components/SidebarBottom.stories.tsx | 40 +++++++++++++++++++ src/{ => components}/SidebarBottom.tsx | 15 ++++--- src/{ => components}/SidebarTop.tsx | 16 ++++---- src/manager.tsx | 4 +- .../VisualTests/VisualTests.stories.tsx | 10 +---- 5 files changed, 61 insertions(+), 24 deletions(-) create mode 100644 src/components/SidebarBottom.stories.tsx rename src/{ => components}/SidebarBottom.tsx (84%) rename src/{ => components}/SidebarTop.tsx (94%) diff --git a/src/components/SidebarBottom.stories.tsx b/src/components/SidebarBottom.stories.tsx new file mode 100644 index 00000000..4141a6c8 --- /dev/null +++ b/src/components/SidebarBottom.stories.tsx @@ -0,0 +1,40 @@ +import { action } from "@storybook/addon-actions"; + +import { ADDON_ID } from "../constants"; +import { SidebarBottomBase } from "./SidebarBottom"; + +export default { + component: SidebarBottomBase, + args: { + api: { experimental_setFilter: action("experimental_setFilter"), emit: action("emit") }, + }, +}; + +export const Changes = { + args: { + status: { + one: { [ADDON_ID]: { status: "warn" } }, + two: { [ADDON_ID]: { status: "warn" } }, + }, + }, +}; + +export const Errors = { + args: { + status: { + one: { [ADDON_ID]: { status: "error" } }, + two: { [ADDON_ID]: { status: "error" } }, + }, + }, +}; + +export const Both = { + args: { + status: { + one: { [ADDON_ID]: { status: "warn" } }, + two: { [ADDON_ID]: { status: "warn" } }, + three: { [ADDON_ID]: { status: "error" } }, + four: { [ADDON_ID]: { status: "error" } }, + }, + }, +}; diff --git a/src/SidebarBottom.tsx b/src/components/SidebarBottom.tsx similarity index 84% rename from src/SidebarBottom.tsx rename to src/components/SidebarBottom.tsx index 8e1ecb66..c7eea8e9 100644 --- a/src/SidebarBottom.tsx +++ b/src/components/SidebarBottom.tsx @@ -1,10 +1,10 @@ -import { type API, useStorybookState } from "@storybook/manager-api"; +import { type API, type State, useStorybookState } from "@storybook/manager-api"; import { styled } from "@storybook/theming"; import type { API_FilterFunction } from "@storybook/types"; import React, { useCallback, useEffect } from "react"; -import { SidebarToggleButton } from "./components/SidebarToggleButton"; -import { ADDON_ID, ENABLE_FILTER } from "./constants"; +import { ADDON_ID, ENABLE_FILTER } from "../constants"; +import { SidebarToggleButton } from "./SidebarToggleButton"; const filterNone: API_FilterFunction = () => true; const filterWarn: API_FilterFunction = ({ status }) => status?.[ADDON_ID]?.status === "warn"; @@ -26,13 +26,13 @@ const Wrapper = styled.div({ interface SidebarBottomProps { api: API; + status: State["status"]; } -export const SidebarBottom = ({ api }: SidebarBottomProps) => { +export const SidebarBottomBase = ({ api, status }: SidebarBottomProps) => { const [showWarnings, setShowWarnings] = React.useState(false); const [showErrors, setShowErrors] = React.useState(false); - const { status } = useStorybookState(); const warnings = Object.values(status).filter((value) => value[ADDON_ID]?.status === "warn"); const errors = Object.values(status).filter((value) => value[ADDON_ID]?.status === "error"); const hasWarnings = warnings.length > 0; @@ -74,3 +74,8 @@ export const SidebarBottom = ({ api }: SidebarBottomProps) => { ); }; + +export const SidebarBottom = (props: Omit) => { + const { status } = useStorybookState(); + return ; +}; diff --git a/src/SidebarTop.tsx b/src/components/SidebarTop.tsx similarity index 94% rename from src/SidebarTop.tsx rename to src/components/SidebarTop.tsx index 2ca4c9f4..b64e723b 100644 --- a/src/SidebarTop.tsx +++ b/src/components/SidebarTop.tsx @@ -4,7 +4,6 @@ import { color } from "@storybook/theming"; import pluralize from "pluralize"; import React, { useCallback, useContext, useEffect, useRef } from "react"; -import { SidebarTopButton } from "./components/SidebarTopButton"; import { ADDON_ID, CONFIG_INFO, @@ -13,13 +12,14 @@ import { IS_OUTDATED, LOCAL_BUILD_PROGRESS, PANEL_ID, -} from "./constants"; -import { ConfigInfoPayload, LocalBuildProgress } from "./types"; -import { useAccessToken } from "./utils/graphQLClient"; -import { TelemetryContext } from "./utils/TelemetryContext"; -import { useBuildEvents } from "./utils/useBuildEvents"; -import { useProjectId } from "./utils/useProjectId"; -import { useSharedState } from "./utils/useSharedState"; +} from "../constants"; +import { ConfigInfoPayload, LocalBuildProgress } from "../types"; +import { useAccessToken } from "../utils/graphQLClient"; +import { TelemetryContext } from "../utils/TelemetryContext"; +import { useBuildEvents } from "../utils/useBuildEvents"; +import { useProjectId } from "../utils/useProjectId"; +import { useSharedState } from "../utils/useSharedState"; +import { SidebarTopButton } from "./SidebarTopButton"; interface SidebarTopProps { api: API; diff --git a/src/manager.tsx b/src/manager.tsx index 78980477..d5fe8697 100644 --- a/src/manager.tsx +++ b/src/manager.tsx @@ -4,10 +4,10 @@ import { color } from "@storybook/theming"; import { Addon_TypesEnum } from "@storybook/types"; import React from "react"; +import { SidebarBottom } from "./components/SidebarBottom"; +import { SidebarTop } from "./components/SidebarTop"; import { ADDON_ID, PANEL_ID, SIDEBAR_BOTTOM_ID, SIDEBAR_TOP_ID } from "./constants"; import { Panel } from "./Panel"; -import { SidebarBottom } from "./SidebarBottom"; -import { SidebarTop } from "./SidebarTop"; let heartbeatTimeout: NodeJS.Timeout; const expectHeartbeat = (api: API) => { diff --git a/src/screens/VisualTests/VisualTests.stories.tsx b/src/screens/VisualTests/VisualTests.stories.tsx index baa1f452..27432d7d 100644 --- a/src/screens/VisualTests/VisualTests.stories.tsx +++ b/src/screens/VisualTests/VisualTests.stories.tsx @@ -3,15 +3,7 @@ import { VariablesOf } from "@graphql-typed-document-node/core"; import type { Meta, StoryObj } from "@storybook/react"; import { expect, fn } from "@storybook/test"; -import { - findByLabelText, - findByRole, - fireEvent, - screen, - userEvent, - waitFor, - within, -} from "@storybook/testing-library"; +import { findByLabelText, findByRole, fireEvent, waitFor } from "@storybook/testing-library"; import { delay, HttpResponse } from "msw"; import React from "react"; From 78c58d0d52d98936b6bfb629bd2529d34d30250f Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Tue, 25 Jun 2024 15:24:35 +0200 Subject: [PATCH 4/4] Ignore storybookBuildDir property for VTA builds --- src/constants.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/constants.ts b/src/constants.ts index a9056115..d24b86f6 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -47,6 +47,8 @@ export const CONFIG_OVERRIDES = { skip: false, // Don't check for CLI updates skipUpdateCheck: true, + // VTA doesn't support "manual" Storybook builds + storybookBuildDir: undefined, }; export const DOCS_URL = "https://www.chromatic.com/docs/visual-tests-addon";