Skip to content

Commit

Permalink
reimplement storybook & chromatic (#128)
Browse files Browse the repository at this point in the history
  • Loading branch information
DaveDarsa authored Jun 20, 2023
1 parent f1ba3b4 commit 080ae99
Show file tree
Hide file tree
Showing 173 changed files with 7,998 additions and 2,895 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/chromatic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# .github/workflows/chromatic.yml

# Workflow name
name: 'Chromatic'

# Event for the workflow
on: push

# List of jobs
jobs:
chromatic-deployment:
# Operating System
runs-on: ubuntu-latest
# Job steps
steps:
- uses: actions/checkout@v3
with:
fetch-depth: "0"
- name: Install dependencies
# 👇 Install dependencies with the same package manager used in the project (replace it as needed), e.g. yarn, npm, pnpm
run: yarn
# 👇 Adds Chromatic as a step in the workflow
- name: Publish to Chromatic
uses: chromaui/action@v1
# Chromatic GitHub Action options
with:
# 👇 Chromatic projectToken, refer to the manage page to obtain it.
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
31 changes: 0 additions & 31 deletions .storybook/Home.stories.js

This file was deleted.

4 changes: 0 additions & 4 deletions .storybook/addons.js

This file was deleted.

10 changes: 0 additions & 10 deletions .storybook/components/Lipsum.js

This file was deleted.

73 changes: 0 additions & 73 deletions .storybook/config.js

This file was deleted.

13 changes: 0 additions & 13 deletions .storybook/decorators/AnonymousUser.js

This file was deleted.

78 changes: 51 additions & 27 deletions .storybook/decorators/ApiConnection.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { ApolloProvider } from 'react-apollo';

import getConfig from 'next/config';

import { ApolloProvider as ApolloHooksProvider } from '@apollo/react-hooks';
import { action } from '@storybook/addon-actions';
import typeDefs from 'api/dist/typeDefs';
import introspectionQueryResultData from 'api/src/fragmentTypes.json';
import mocks, { seed } from 'api/src/mocks';
import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';
import { SchemaLink } from 'apollo-link-schema';
import { addMockFunctionsToSchema, makeExecutableSchema } from 'graphql-tools';
import { AuthContext } from 'lib/Authenticator';

const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData,
});
import { createHttpLink } from 'apollo-link-http';

// Make a GraphQL schema without resolvers.
const schema = makeExecutableSchema({ typeDefs });
import { AuthContext } from '../../src/lib/Authenticator';

// Add mocks, modifies schema in place.
addMockFunctionsToSchema({ schema, mocks });
const publicRuntimeConfig = getConfig();

// Create a mocked Apollo client for the ApolloProvider.
const client = new ApolloClient({
cache: new InMemoryCache({ fragmentMatcher }),
link: new SchemaLink({ schema }),
});
const defaultOptions = {
watchQuery: {
fetchPolicy: 'no-cache',
errorPolicy: 'ignore',
},
query: {
fetchPolicy: 'no-cache',
errorPolicy: 'all',
},
};

// Mock the src/lib/Authenticator and lib/withLocalAuth.
const auth = {
Expand All @@ -35,17 +32,44 @@ const auth = {
provider: 'local-auth',
providerData: {},
user: {
username: 'admin',
username: 'Admin',
},
};

export default storyFn => {
// Generate consistent results by seeding the mocks generator before each
// story.
seed();
const withMockAuth = Story => {
const [_controller] = useState(new AbortController());

// Create a mocked Apollo client for the ApolloProvider.
const client = new ApolloClient({
cache: new InMemoryCache(),
link: createHttpLink({
uri: publicRuntimeConfig.GRAPHQL_API,
fetchOptions: {
signal: _controller.signal,
},
}),
defaultOptions,
});

/*
Every time the decorator unmounts, all previous gql requests get cancelled,
makes it easy to handle mocked infinite loading queries that do not get re-executed.
*/
useEffect(() => {
return () => {
_controller.abort();
};
}, []);
return (
<AuthContext.Provider value={auth}>
<ApolloProvider client={client}>{storyFn()}</ApolloProvider>
<ApolloProvider client={client}>
<ApolloHooksProvider client={client}>
<Story />
</ApolloHooksProvider>
</ApolloProvider>
</AuthContext.Provider>
);
};

export default withMockAuth;
12 changes: 0 additions & 12 deletions .storybook/decorators/GlobalStyles.js

This file was deleted.

40 changes: 40 additions & 0 deletions .storybook/decorators/withButtonOverrides.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { useEffect } from 'react';

import { action } from '@storybook/addon-actions';
import { StoryFn } from '@storybook/react';

/*
For mocking component button functionality only:
the decorator intercepts and overrides component level button actions instead of trying to execute a mutation
*/
const withButtonOverrides = (domQuery: string, actionType: string, actionDescription: string) => {
return (StoryFn: StoryFn) => {
useEffect(() => {
const handleButtonClick = (event: Event) => {
event.preventDefault();
event.stopPropagation();
// Manually trigger the action logging
action(actionDescription)(event);
};

const buttons = document.querySelectorAll(domQuery);

// Override the click event handler for each button
buttons.forEach(button => {
button.addEventListener(actionType, handleButtonClick);
});

return () => {
// Cleanup: Remove the overridden click event handlers
buttons.forEach(button => {
button.removeEventListener(actionType, handleButtonClick);
});
};
}, []);

return <StoryFn />;
};
};

export default withButtonOverrides;
18 changes: 18 additions & 0 deletions .storybook/decorators/withLoadingSkeletons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';

import ThemedSkeletonWrapper from '../../src/styles/ThemedSkeletonWrapper';
import { darkTheme, lightTheme } from '../../src/styles/theme';
const withLoadingSkeletons = (Story, context) => {
const initialTheme = (context.globals.theme === '' || context.globals.theme ==="dark") ? 'dark' : "light";
const {
//@ts-ignore
skeleton: { base, highlight },
} = initialTheme === 'dark' ? darkTheme : lightTheme;

return (
<ThemedSkeletonWrapper baseColor={base} highlightColor={highlight}>
<Story />
</ThemedSkeletonWrapper>
);
};
export default withLoadingSkeletons;
36 changes: 36 additions & 0 deletions .storybook/decorators/withMockedAppContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { useEffect, useState } from 'react';

import { useGlobals } from '@storybook/client-api';

import { AppContext } from '../../src/pages/_app';

const withMockedAppContext = initialTheme => (Story, context) => {
const [theme, setTheme] = useState(initialTheme);
const [globals, setGlobals] = useGlobals();
const toggleTheme = () => {
setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light'));
};
const isDocsPage = context.viewMode === 'docs';

useEffect(() => {
if (!isDocsPage) {
const initialTheme = (context.globals.theme === '' || context.globals.theme ==="dark") ? 'dark' : "light";
const newBg = initialTheme === 'dark' ? '#333333' : '#F8F8F8';

setGlobals({
...globals,
backgrounds: {
value: newBg,
},
});
}
}, [globals.theme]);

return (
<AppContext.Provider value={{ theme, toggleTheme }}>
<Story {...context} />
</AppContext.Provider>
);
};

export default withMockedAppContext;
13 changes: 13 additions & 0 deletions .storybook/decorators/withTourProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';

import { TourContextProvider } from '../../src/tours/TourContext';

const withTourProvider = Story => {
return (
<TourContextProvider>
<Story />
</TourContextProvider>
);
};

export default withTourProvider;
Binary file removed .storybook/lagoon.png
Binary file not shown.
Loading

0 comments on commit 080ae99

Please sign in to comment.