Skip to content

Commit

Permalink
ci: add storybook (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
pyphilia authored Feb 27, 2024
1 parent f2e1746 commit 81075b5
Show file tree
Hide file tree
Showing 9 changed files with 12,503 additions and 3,216 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/storybook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Deploy Storybook to Github Pages
on:
# Allow the workflow to be manually triggered
workflow_dispatch:
# Automatically trigger on push on main
push:
branches:
- main

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: 'pages'
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Yarn install and cache
uses: graasp/graasp-deploy/.github/actions/yarn-install-and-cache@v1

- name: Build storybook
run: yarn storybook:build

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./storybook-static

# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
51 changes: 51 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: CI tests

on:
push:
branches:
- 'main'
merge_group:
pull_request:

jobs:
test:
timeout-minutes: 20
runs-on: ubuntu-latest
concurrency:
group: storybook-tests-${{ github.head_ref || github.ref }}
# we do not cancel the workflows in progress as the runs are quite fast.
cancel-in-progress: false
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install dependencies
run: yarn

- name: Check code style and linting
run: yarn prettier:check && yarn lint

- name: Build # ensures type-checks and compiles
run: yarn build

- name: Get Latest playwright version
run: echo "PLAYWRIGHT_VERSION=$(npm show playwright version)" >> $GITHUB_ENV
- name: Cache playwright binaries
uses: actions/cache@v4
id: playwright-cache
with:
path: |
~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }}
- name: Install playwright
run: npx playwright install --with-deps
if: steps.playwright-cache.outputs.cache-hit != 'true'

- name: Build storybook
run: yarn storybook:build --quiet

- name: Run storybook tests
run: |
npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
"npx http-server storybook-static --port 6006 --silent" \
"npx wait-on http://127.0.0.1:6006 && yarn storybook:test"
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,6 @@ cypress/videos
!.yarn/versions
/test-results/
/playwright-report/
/playwright/.cache/
/playwright/.cache/

storybook-static
28 changes: 28 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { StorybookConfig } from '@storybook/react-vite';
import { dirname, join } from 'path';

/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
function getAbsolutePath(value: string): any {
return dirname(require.resolve(join(value, 'package.json')));
}
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
getAbsolutePath('@storybook/addon-links'),
getAbsolutePath('@storybook/addon-essentials'),
getAbsolutePath('@storybook/addon-onboarding'),
getAbsolutePath('@storybook/addon-interactions'),
getAbsolutePath('@storybook/addon-coverage'),
],
framework: {
name: getAbsolutePath('@storybook/react-vite'),
options: {},
},
docs: {
autodocs: 'tag',
},
};
export default config;
42 changes: 42 additions & 0 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'react-quill/dist/quill.snow.css';

import { CssBaseline } from '@mui/material';
import { ThemeProvider } from '@mui/system';

import { theme } from '@graasp/ui';

import type { Preview } from '@storybook/react';

const preview: Preview = {
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;

export const decorators = [
(Story, { globals }) => {
return (
<ThemeProvider
theme={{
...theme,
direction: globals.direction,
palette: {
...theme.palette,
mode: globals.theme,
},
}}
>
<CssBaseline />
<Story />
</ThemeProvider>
);
},
];
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
![NPM package downloads per month](https://img.shields.io/npm/dm/@graasp/map?color=green)
![typescript version](https://img.shields.io/github/package-json/dependency-version/graasp/graasp-map/dev/typescript)

[![Storybook deployment](https://img.shields.io/badge/storybook-ui-%23FF4785?logo=storybook)](https://graasp.github.io/graasp-map/)
<a href="https://gitlocalize.com/repo/9355?utm_source=badge"> <img src="https://gitlocalize.com/repo/9355/whole_project/badge.svg" /> </a>
29 changes: 27 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@
"test": "yarn build && yarn cypress:ci",
"hooks:uninstall": "husky uninstall",
"hooks:install": "husky install",
"prepack": "yarn build"
"prepack": "yarn build",
"storybook": "storybook dev -p 6006",
"storybook:build": "storybook build",
"storybook:preview": "http-server storybook-static --port 6006 --silent",
"storybook:test": "test-storybook --coverage",
"storybook:test-ci": "wait-on http://127.0.0.1:6006 && yarn storybook:test"
},
"dependencies": {
"@emotion/react": "11.11.3",
Expand All @@ -72,6 +77,18 @@
"@commitlint/cli": "17.8.1",
"@commitlint/config-conventional": "17.8.1",
"@graasp/query-client": "2.6.3",
"@storybook/addon-coverage": "1.0.0",
"@storybook/addon-essentials": "7.6.17",
"@storybook/addon-interactions": "7.6.17",
"@storybook/addon-links": "7.6.17",
"@storybook/addon-onboarding": "^1.0.11",
"@storybook/blocks": "7.6.17",
"@storybook/jest": "0.2.3",
"@storybook/react": "7.6.17",
"@storybook/react-vite": "7.6.17",
"@storybook/test": "7.6.17",
"@storybook/test-runner": "0.16.0",
"@storybook/testing-library": "0.2.2",
"@trivago/prettier-plugin-sort-imports": "4.3.0",
"@types/leaflet": "^1.9.8",
"@types/react": "^18.2.48",
Expand All @@ -88,8 +105,11 @@
"eslint-plugin-react": "7.33.2",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"eslint-plugin-storybook": "0.8.0",
"http-server": "14.1.1",
"prettier": "3.2.5",
"rollup-plugin-visualizer": "5.12.0",
"storybook": "7.6.17",
"typescript": "^5.3.3",
"vite": "5.1.4",
"vite-plugin-css-injected-by-js": "3.4.0",
Expand All @@ -109,5 +129,10 @@
"react-dom": "*",
"react-i18next": "^14.0.0"
},
"packageManager": "[email protected]"
"packageManager": "[email protected]",
"eslintConfig": {
"extends": [
"plugin:storybook/recommended"
]
}
}
39 changes: 39 additions & 0 deletions src/components/Map.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { MemberFactory } from '@graasp/sdk';

import { expect } from '@storybook/jest';
import type { Meta, StoryObj } from '@storybook/react';
import { within } from '@storybook/testing-library';

import MapComponent from './Map';

const meta = {
title: 'Map',
component: MapComponent,
} satisfies Meta<typeof MapComponent>;
export default meta;

type Story = StoryObj<typeof meta>;

export const Map = {
args: {
itemId: 'd5a1c73d-cd4d-4f20-8a91-3c689ee87ea4',
viewItem: () => ({}) as any,
currentMember: MemberFactory(),
useDeleteItemGeolocation: () => ({}) as any,
useItemsInMap: () => ({ data: [] }) as any,
useAddressFromGeolocation: () => ({ data: 'address' }) as any,
usePostItem: () => ({}) as any,
useRecycleItems: () => ({}) as any,
},
decorators: [
(Story) => (
<div style={{ margin: 'auto', width: '90vw', height: '90vh' }}>
<Story />
</div>
),
],
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(canvas.getByLabelText('Search')).toBeInTheDocument();
},
} satisfies Story;
Loading

0 comments on commit 81075b5

Please sign in to comment.