Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Storybook: Enable interactive stories #30294

Draft
wants to merge 1 commit into
base: tr/fix-commits-popovr
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/storybook/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ const config = {
'storybook-dark-mode',
'@storybook/addon-a11y',
'@storybook/addon-toolbars',
'@storybook/addon-interactions',
],

core: {
Expand Down
46 changes: 46 additions & 0 deletions client/web/src/repo/RevisionsPopover/RevisionsPopover.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as DOMTestingLibrary from '@testing-library/dom'
import * as DOMQueries from '@testing-library/dom/types/queries'
import * as ReactTestingLibrary from '@testing-library/react'
import userEvent from '@testing-library/user-event'

import { waitForNextApolloResponse } from '@sourcegraph/shared/src/testing/apollo'

/** We either have the render if using React, or the HTML element if using the DOM */
type HTMLContainer = HTMLElement

interface UserActionMap {
selectBranchTab: () => Promise<void>
selectTagTab: () => Promise<void>
selectCommitTab: () => Promise<void>
focusGitReference: () => void
}

export const revisionPopoverUserActions = (renderResult: HTMLContainer): UserActionMap => {
const boundFunctions:
| DOMTestingLibrary.BoundFunctions<typeof DOMQueries>
| ReactTestingLibrary.BoundFunctions<typeof DOMQueries> = DOMTestingLibrary.within<typeof DOMQueries>(
renderResult
)

return {
selectBranchTab: async () => {
const branchTab = boundFunctions.getByText('Branches')
userEvent.click(branchTab)
await waitForNextApolloResponse()
},
selectTagTab: async () => {
const tagsTab = boundFunctions.getByText('Tags')
userEvent.click(tagsTab)
await waitForNextApolloResponse()
},
selectCommitTab: async () => {
const commitsTab = boundFunctions.getByText('Commits')
userEvent.click(commitsTab)
await waitForNextApolloResponse()
},
focusGitReference: () => {
const gitReference = boundFunctions.getAllByTestId('git-ref-node')[0]
gitReference.focus()
},
}
}
81 changes: 38 additions & 43 deletions client/web/src/repo/RevisionsPopover/RevisionsPopover.story.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,50 @@
import { Meta } from '@storybook/react'
import React, { useMemo } from 'react'
import { ComponentMeta, ComponentStory } from '@storybook/react'
import React from 'react'

import { WebStory } from '@sourcegraph/web/src/components/WebStory'
import { WebStory } from '../../components/WebStory'

import { RevisionsPopover } from './RevisionsPopover'
import { revisionPopoverUserActions } from './RevisionsPopover.actions'
import { MOCK_PROPS, MOCK_REQUESTS } from './RevisionsPopover.mocks'

import { LAST_TAB_STORAGE_KEY } from '.'

const Story: Meta = {
const config: ComponentMeta<typeof RevisionsPopover> = {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'web/RevisionsPopover',

decorators: [
story => (
<WebStory
mocks={MOCK_REQUESTS}
initialEntries={[{ pathname: `/${MOCK_PROPS.repoName}` }]}
// Can't utilise loose mocking here as the commit/branch requests use the same operations just with different variables
useStrictMocking={true}
>
{() => <div className="container mt-3">{story()}</div>}
</WebStory>
),
],

parameters: {
component: RevisionsPopover,
design: {
type: 'figma',
name: 'Figma',
url:
'https://www.figma.com/file/NIsN34NH7lPu04olBzddTw/Design-Refresh-Systemization-source-of-truth?node-id=954%3A2161',
},
},
component: RevisionsPopover,
}

export default Story

interface RevisionsPopoverStoryProps {
initialTabIndex: number
export default config

const Template: ComponentStory<typeof RevisionsPopover> = templateProps => (
<WebStory
mocks={MOCK_REQUESTS}
initialEntries={[{ pathname: `/${MOCK_PROPS.repoName}` }]}
// Can't utilise loose mocking here as the commit/branch requests use the same operations just with different variables
useStrictMocking={true}
>
{webStoryProps => <RevisionsPopover {...webStoryProps} {...templateProps} {...MOCK_PROPS} />}
</WebStory>
)

export const RevisionsPopoverBranches = Template.bind({})
RevisionsPopoverBranches.play = async ({ canvasElement }) => {
const { selectBranchTab, focusGitReference } = revisionPopoverUserActions(canvasElement)
await selectBranchTab()
focusGitReference()
}

const RevisionsPopoverStory: React.FunctionComponent<RevisionsPopoverStoryProps> = ({ initialTabIndex }) => {
// Ensure we have prepared the correct tab index before we render
useMemo(() => {
localStorage.setItem(LAST_TAB_STORAGE_KEY, initialTabIndex.toString())
}, [initialTabIndex])

return <RevisionsPopover {...MOCK_PROPS} />
export const RevisionsPopoverTags = Template.bind({})
RevisionsPopoverTags.play = async ({ canvasElement }) => {
const { selectTagTab, focusGitReference } = revisionPopoverUserActions(canvasElement)
await selectTagTab()
focusGitReference()
}

export const RevisionsPopoverBranches = () => <RevisionsPopoverStory initialTabIndex={0} />
export const RevisionsPopoverTags = () => <RevisionsPopoverStory initialTabIndex={1} />
export const RevisionsPopoverCommits = () => <RevisionsPopoverStory initialTabIndex={2} />
export const RevisionsPopoverCommits = Template.bind({})
RevisionsPopoverCommits.play = async ({ canvasElement }) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const { selectCommitTab } = revisionPopoverUserActions(canvasElement)
await selectCommitTab()
}
25 changes: 13 additions & 12 deletions client/web/src/repo/RevisionsPopover/RevisionsPopover.test.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { cleanup, within, fireEvent, act } from '@testing-library/react'
import * as ReactTestingLibrary from '@testing-library/react'
import React from 'react'

import { MockedTestProvider, waitForNextApolloResponse } from '@sourcegraph/shared/src/testing/apollo'
import { renderWithRouter, RenderWithRouterResult } from '@sourcegraph/shared/src/testing/render-with-router'

import { RevisionsPopover, RevisionsPopoverProps } from './RevisionsPopover'
import { revisionPopoverUserActions } from './RevisionsPopover.actions'
import { MOCK_PROPS, MOCK_REQUESTS } from './RevisionsPopover.mocks'

describe('RevisionsPopover', () => {
let renderResult: RenderWithRouterResult
const { cleanup, within, fireEvent, act } = ReactTestingLibrary

const fetchMoreNodes = async (currentTab: HTMLElement) => {
fireEvent.click(within(currentTab).getByText('Show more'))
Expand All @@ -33,9 +35,8 @@ describe('RevisionsPopover', () => {
beforeEach(async () => {
renderResult = renderPopover()

fireEvent.click(renderResult.getByText('Branches'))
await waitForNextApolloResponse()

const { selectBranchTab } = revisionPopoverUserActions(renderResult.container)
await selectBranchTab()
branchesTab = renderResult.getByRole('tabpanel', { name: 'Branches' })
})

Expand Down Expand Up @@ -91,8 +92,8 @@ describe('RevisionsPopover', () => {
cleanup()
renderResult = renderPopover({ showSpeculativeResults: true })

fireEvent.click(renderResult.getByText('Branches'))
await waitForNextApolloResponse()
const { selectBranchTab } = revisionPopoverUserActions(renderResult.container)
await selectBranchTab()

branchesTab = renderResult.getByRole('tabpanel', { name: 'Branches' })
})
Expand Down Expand Up @@ -121,8 +122,8 @@ describe('RevisionsPopover', () => {
beforeEach(async () => {
renderResult = renderPopover()

fireEvent.click(renderResult.getByText('Tags'))
await waitForNextApolloResponse()
const { selectTagTab } = revisionPopoverUserActions(renderResult.container)
await selectTagTab()

tagsTab = renderResult.getByRole('tabpanel', { name: 'Tags' })
})
Expand Down Expand Up @@ -166,8 +167,8 @@ describe('RevisionsPopover', () => {
beforeEach(async () => {
renderResult = renderPopover()

fireEvent.click(renderResult.getByText('Commits'))
await waitForNextApolloResponse()
const { selectCommitTab } = revisionPopoverUserActions(renderResult.container)
await selectCommitTab()

commitsTab = renderResult.getByRole('tabpanel', { name: 'Commits' })
})
Expand Down Expand Up @@ -206,8 +207,8 @@ describe('RevisionsPopover', () => {
cleanup()
renderResult = renderPopover({ currentRev: 'non-existent-revision' })

fireEvent.click(renderResult.getByText('Commits'))
await waitForNextApolloResponse()
const { selectCommitTab } = revisionPopoverUserActions(renderResult.container)
await selectCommitTab()

commitsTab = renderResult.getByRole('tabpanel', { name: 'Commits' })
})
Expand Down
36 changes: 19 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,24 +127,26 @@
"@sourcegraph/prettierrc": "^3.0.3",
"@sourcegraph/stylelint-config": "^1.3.0",
"@sourcegraph/tsconfig": "^4.0.1",
"@storybook/addon-a11y": "^6.3.12",
"@storybook/addon-actions": "^6.3.12",
"@storybook/addon-a11y": "^6.4.14",
"@storybook/addon-actions": "^6.4.14",
"@storybook/addon-console": "^1.2.3",
"@storybook/addon-knobs": "^6.3.1",
"@storybook/addon-links": "^6.3.12",
"@storybook/addon-storyshots": "^6.3.12",
"@storybook/addon-storyshots-puppeteer": "^6.3.12",
"@storybook/addon-toolbars": "^6.3.12",
"@storybook/addons": "^6.3.12",
"@storybook/api": "^6.3.12",
"@storybook/builder-webpack5": "^6.3.12",
"@storybook/client-api": "^6.3.12",
"@storybook/components": "^6.3.12",
"@storybook/core": "^6.3.12",
"@storybook/core-events": "^6.3.12",
"@storybook/manager-webpack5": "^6.3.12",
"@storybook/react": "^6.3.12",
"@storybook/theming": "^6.3.12",
"@storybook/addon-interactions": "^6.4.14",
"@storybook/addon-knobs": "^6.4.0",
"@storybook/addon-links": "^6.4.14",
"@storybook/addon-storyshots": "^6.4.14",
"@storybook/addon-storyshots-puppeteer": "^6.4.14",
"@storybook/addon-toolbars": "^6.4.14",
"@storybook/addons": "^6.4.14",
"@storybook/api": "^6.4.14",
"@storybook/builder-webpack5": "^6.4.14",
"@storybook/client-api": "^6.4.14",
"@storybook/components": "^6.4.14",
"@storybook/core": "^6.4.14",
"@storybook/core-events": "^6.4.14",
"@storybook/manager-webpack5": "^6.4.14",
"@storybook/react": "^6.4.14",
"@storybook/testing-library": "^0.0.8",
"@storybook/theming": "^6.4.14",
"@terminus-term/to-string-loader": "^1.1.7-beta.1",
"@testing-library/dom": "^8.11.1",
"@testing-library/jest-dom": "^5.11.9",
Expand Down
Loading