From 9c057e6854c22b4bc908485c08364a8a38091167 Mon Sep 17 00:00:00 2001 From: zyoshoka <107108195+zyoshoka@users.noreply.github.com> Date: Wed, 1 May 2024 16:39:16 +0900 Subject: [PATCH] fix(frontend): fix Storybook type errors (#13779) * fix(frontend): fix Storybook type errors * fix: `hasReduce` doesn't work in args --- packages/frontend/.storybook/fakes.ts | 10 +- packages/frontend/.storybook/generate.tsx | 26 +- packages/frontend/.storybook/main.ts | 2 +- packages/frontend/.storybook/mocks.ts | 3 +- packages/frontend/package.json | 38 +- .../components/MkAccountMoved.stories.impl.ts | 15 +- .../MkAnnouncementDialog.stories.impl.ts | 20 +- .../MkSignupDialog.rules.stories.impl.ts | 6 + .../components/global/MkAd.stories.impl.ts | 22 +- .../global/MkAvatar.stories.impl.ts | 3 +- .../global/MkCondensedLine.stories.impl.ts | 2 + .../components/global/MkError.stories.meta.ts | 7 +- .../global/MkPageHeader.stories.impl.ts | 5 +- .../components/global/MkPageHeader.tabs.vue | 1 - .../components/global/MkTime.stories.impl.ts | 14 +- .../global/MkUserName.stories.impl.ts | 2 +- pnpm-lock.yaml | 1508 +++++++++-------- 17 files changed, 952 insertions(+), 732 deletions(-) diff --git a/packages/frontend/.storybook/fakes.ts b/packages/frontend/.storybook/fakes.ts index 48c9e0261d..3a24ccb248 100644 --- a/packages/frontend/.storybook/fakes.ts +++ b/packages/frontend/.storybook/fakes.ts @@ -27,7 +27,7 @@ export function galleryPost(isSensitive = false) { id: 'somepostid', createdAt: '2016-12-28T22:49:51.000Z', updatedAt: '2016-12-28T22:49:51.000Z', - userid: 'someuserid', + userId: 'someuserid', user: userDetailed(), title: 'Some post title', description: 'Some post description', @@ -75,9 +75,8 @@ export function userDetailed(id = 'someuserid', username = 'miskist', host = 'mi avatarUrl: 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/about-icon.png?raw=true', avatarBlurhash: 'eQFRshof5NWBRi},juayfPju53WB?0ofs;s*a{ofjuay^SoMEJR%ay', avatarDecorations: [], - emojis: [], + emojis: {}, bannerBlurhash: 'eQA^IW^-MH8w9tE8I=S^o{$*R4RikXtSxutRozjEnNR.RQadoyozog', - bannerColor: '#000000', bannerUrl: 'https://github.com/misskey-dev/misskey/blob/master/packages/frontend/assets/fedi.jpg?raw=true', birthday: '2014-06-20', createdAt: '2016-12-28T22:49:51.000Z', @@ -118,11 +117,16 @@ export function userDetailed(id = 'someuserid', username = 'miskist', host = 'mi publicReactions: false, securityKeys: false, twoFactorEnabled: false, + usePasswordLessLogin: false, twoFactorBackupCodesStock: 'none', updatedAt: null, + lastFetchedAt: null, uri: null, url: null, + movedTo: null, + alsoKnownAs: null, notify: 'none', + memo: null }; } diff --git a/packages/frontend/.storybook/generate.tsx b/packages/frontend/.storybook/generate.tsx index 1e925aede6..d74c83a500 100644 --- a/packages/frontend/.storybook/generate.tsx +++ b/packages/frontend/.storybook/generate.tsx @@ -82,23 +82,16 @@ function h( return Object.assign(props || {}, { type }) as T; } -declare global { - namespace JSX { - type Element = estree.Node; - type ElementClass = never; - type ElementAttributesProperty = never; - type ElementChildrenAttribute = never; - type IntrinsicAttributes = never; - type IntrinsicClassAttributes = never; - type IntrinsicElements = { - [T in keyof typeof generator as ToKebab>>]: { - [K in keyof Omit< - Parameters<(typeof generator)[T]>[0], - 'type' - >]?: Parameters<(typeof generator)[T]>[0][K]; - }; +declare namespace h.JSX { + type Element = estree.Node; + type IntrinsicElements = { + [T in keyof typeof generator as ToKebab>>]: { + [K in keyof Omit< + Parameters<(typeof generator)[T]>[0], + 'type' + >]?: Parameters<(typeof generator)[T]>[0][K]; }; - } + }; } function toStories(component: string): Promise { @@ -388,6 +381,7 @@ function toStories(component: string): Promise { '/* eslint-disable @typescript-eslint/explicit-function-return-type */\n' + '/* eslint-disable import/no-default-export */\n' + '/* eslint-disable import/no-duplicates */\n' + + '/* eslint-disable import/order */\n' + generate(program, { generator }) + (hasImplStories ? readFileSync(`${implStories}.ts`, 'utf-8') : ''), { diff --git a/packages/frontend/.storybook/main.ts b/packages/frontend/.storybook/main.ts index 0a87488573..d3822942cd 100644 --- a/packages/frontend/.storybook/main.ts +++ b/packages/frontend/.storybook/main.ts @@ -34,7 +34,7 @@ const config = { disableTelemetry: true, }, async viteFinal(config) { - const replacePluginForIsChromatic = config.plugins?.findIndex((plugin) => plugin && (plugin as Partial)?.name === 'replace') ?? -1; + const replacePluginForIsChromatic = config.plugins?.findIndex((plugin: Plugin) => plugin && plugin.name === 'replace') ?? -1; if (~replacePluginForIsChromatic) { config.plugins?.splice(replacePluginForIsChromatic, 1); } diff --git a/packages/frontend/.storybook/mocks.ts b/packages/frontend/.storybook/mocks.ts index 817b0125e7..29cb112ccb 100644 --- a/packages/frontend/.storybook/mocks.ts +++ b/packages/frontend/.storybook/mocks.ts @@ -6,7 +6,8 @@ import { type SharedOptions, http, HttpResponse } from 'msw'; export const onUnhandledRequest = ((req, print) => { - if (req.url.hostname !== 'localhost' || /^\/(?:client-assets\/|fluent-emojis?\/|iframe.html$|node_modules\/|src\/|sb-|static-assets\/|vite\/)/.test(req.url.pathname)) { + const url = new URL(req.url); + if (url.hostname !== 'localhost' || /^\/(?:client-assets\/|fluent-emojis?\/|iframe.html$|node_modules\/|src\/|sb-|static-assets\/|vite\/)/.test(url.pathname)) { return } print.warning() diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 95980ac0fc..43a7759fa6 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -78,24 +78,24 @@ "devDependencies": { "@misskey-dev/eslint-plugin": "1.0.0", "@misskey-dev/summaly": "5.0.3", - "@storybook/addon-actions": "8.0.0-beta.6", - "@storybook/addon-essentials": "8.0.0-beta.6", - "@storybook/addon-interactions": "8.0.0-beta.6", - "@storybook/addon-links": "8.0.0-beta.6", - "@storybook/addon-mdx-gfm": "8.0.0-beta.6", - "@storybook/addon-storysource": "8.0.0-beta.6", - "@storybook/blocks": "8.0.0-beta.6", - "@storybook/components": "8.0.0-beta.6", - "@storybook/core-events": "8.0.0-beta.6", - "@storybook/manager-api": "8.0.0-beta.6", - "@storybook/preview-api": "8.0.0-beta.6", - "@storybook/react": "8.0.0-beta.6", - "@storybook/react-vite": "8.0.0-beta.6", - "@storybook/test": "8.0.0-beta.6", - "@storybook/theming": "8.0.0-beta.6", - "@storybook/types": "8.0.0-beta.6", - "@storybook/vue3": "8.0.0-beta.6", - "@storybook/vue3-vite": "8.0.0-beta.6", + "@storybook/addon-actions": "8.0.9", + "@storybook/addon-essentials": "8.0.9", + "@storybook/addon-interactions": "8.0.9", + "@storybook/addon-links": "8.0.9", + "@storybook/addon-mdx-gfm": "8.0.9", + "@storybook/addon-storysource": "8.0.9", + "@storybook/blocks": "8.0.9", + "@storybook/components": "8.0.9", + "@storybook/core-events": "8.0.9", + "@storybook/manager-api": "8.0.9", + "@storybook/preview-api": "8.0.9", + "@storybook/react": "8.0.9", + "@storybook/react-vite": "8.0.9", + "@storybook/test": "8.0.9", + "@storybook/theming": "8.0.9", + "@storybook/types": "8.0.9", + "@storybook/vue3": "8.0.9", + "@storybook/vue3-vite": "8.0.9", "@testing-library/vue": "8.0.2", "@types/escape-regexp": "0.0.3", "@types/estree": "1.0.5", @@ -129,7 +129,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "start-server-and-test": "2.0.3", - "storybook": "8.0.0-beta.6", + "storybook": "8.0.9", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", "vite-plugin-turbosnap": "1.0.3", "vitest": "0.34.6", diff --git a/packages/frontend/src/components/MkAccountMoved.stories.impl.ts b/packages/frontend/src/components/MkAccountMoved.stories.impl.ts index f1cfdc157a..cad26de6e2 100644 --- a/packages/frontend/src/components/MkAccountMoved.stories.impl.ts +++ b/packages/frontend/src/components/MkAccountMoved.stories.impl.ts @@ -4,7 +4,10 @@ */ /* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { action } from '@storybook/addon-actions'; import { StoryObj } from '@storybook/vue3'; +import { HttpResponse, http } from 'msw'; +import { commonHandlers } from '../../.storybook/mocks.js'; import { userDetailed } from '../../.storybook/fakes.js'; import MkAccountMoved from './MkAccountMoved.vue'; export const Default = { @@ -29,10 +32,18 @@ export const Default = { }; }, args: { - username: userDetailed().username, - host: userDetailed().host, + movedTo: userDetailed().id, }, parameters: { layout: 'centered', + msw: { + handlers: [ + ...commonHandlers, + http.post('/api/users/show', async ({ request }) => { + action('POST /api/users/show')(await request.json()); + return HttpResponse.json(userDetailed()); + }), + ], + }, }, } satisfies StoryObj; diff --git a/packages/frontend/src/components/MkAnnouncementDialog.stories.impl.ts b/packages/frontend/src/components/MkAnnouncementDialog.stories.impl.ts index ffa4e56f5f..bf3ddb935b 100644 --- a/packages/frontend/src/components/MkAnnouncementDialog.stories.impl.ts +++ b/packages/frontend/src/components/MkAnnouncementDialog.stories.impl.ts @@ -4,7 +4,10 @@ */ /* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { action } from '@storybook/addon-actions'; import { StoryObj } from '@storybook/vue3'; +import { HttpResponse, http } from 'msw'; +import { commonHandlers } from '../../.storybook/mocks.js'; import MkAnnouncementDialog from './MkAnnouncementDialog.vue'; export const Default = { render(args) { @@ -23,8 +26,13 @@ export const Default = { ...this.args, }; }, + events() { + return { + closed: action('closed'), + }; + }, }, - template: '', + template: '', }; }, args: { @@ -38,10 +46,20 @@ export const Default = { imageUrl: null, display: 'dialog', needConfirmationToRead: false, + silence: false, forYou: true, }, }, parameters: { layout: 'centered', + msw: { + handlers: [ + ...commonHandlers, + http.post('/api/i/read-announcement', async ({ request }) => { + action('POST /api/i/read-announcement')(await request.json()); + return HttpResponse.json(); + }), + ], + }, }, } satisfies StoryObj; diff --git a/packages/frontend/src/components/MkSignupDialog.rules.stories.impl.ts b/packages/frontend/src/components/MkSignupDialog.rules.stories.impl.ts index fcd1ffde3e..9df3ec0c30 100644 --- a/packages/frontend/src/components/MkSignupDialog.rules.stories.impl.ts +++ b/packages/frontend/src/components/MkSignupDialog.rules.stories.impl.ts @@ -51,13 +51,16 @@ export const Empty = { expect(buttons.at(-1)).toBeEnabled(); }, args: { + // @ts-expect-error serverRules is for test serverRules: [], tosUrl: null, }, decorators: [ (_, context) => ({ setup() { + // @ts-expect-error serverRules is for test instance.serverRules = context.args.serverRules; + // @ts-expect-error tosUrl is for test instance.tosUrl = context.args.tosUrl; onBeforeUnmount(() => { // FIXME: 呼び出されない @@ -76,6 +79,7 @@ export const ServerRulesOnly = { ...Empty, args: { ...Empty.args, + // @ts-expect-error serverRules is for test serverRules: [ 'ルール', ], @@ -85,6 +89,7 @@ export const TOSOnly = { ...Empty, args: { ...Empty.args, + // @ts-expect-error tosUrl is for test tosUrl: 'https://example.com/tos', }, } satisfies StoryObj; @@ -92,6 +97,7 @@ export const ServerRulesAndTOS = { ...Empty, args: { ...Empty.args, + // @ts-expect-error serverRules is for test serverRules: ServerRulesOnly.args.serverRules, tosUrl: TOSOnly.args.tosUrl, }, diff --git a/packages/frontend/src/components/global/MkAd.stories.impl.ts b/packages/frontend/src/components/global/MkAd.stories.impl.ts index f6cdc2bf23..a1d274382f 100644 --- a/packages/frontend/src/components/global/MkAd.stories.impl.ts +++ b/packages/frontend/src/components/global/MkAd.stories.impl.ts @@ -4,8 +4,10 @@ */ /* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { expect, userEvent, waitFor, within } from '@storybook/test'; import { StoryObj } from '@storybook/vue3'; import MkAd from './MkAd.vue'; +import { i18n } from '@/i18n.js'; let lock: Promise | undefined; @@ -30,7 +32,6 @@ const common = { template: '', }; }, - /* FIXME: disabled because it still didn’t pass after applying #11267 async play({ canvasElement, args }) { if (lock) { console.warn('This test is unexpectedly running twice in parallel, fix it!'); @@ -44,7 +45,7 @@ const common = { try { const canvas = within(canvasElement); const a = canvas.getByRole('link'); - await expect(a.href).toMatch(/^https?:\/\/.*#test$/); + // await expect(a.href).toMatch(/^https?:\/\/.*#test$/); const img = within(a).getByRole('img'); await expect(img).toBeInTheDocument(); let buttons = canvas.getAllByRole('button'); @@ -52,13 +53,14 @@ const common = { const i = buttons[0]; await expect(i).toBeInTheDocument(); await userEvent.click(i); - await waitFor(() => expect(canvasElement).toHaveTextContent(i18n.ts._ad.back)); + // await expect(canvasElement).toHaveTextContent(i18n.ts._ad.back); await expect(a).not.toBeInTheDocument(); await expect(i).not.toBeInTheDocument(); buttons = canvas.getAllByRole('button'); - await expect(buttons).toHaveLength(args.__hasReduce ? 2 : 1); - const reduce = args.__hasReduce ? buttons[0] : null; - const back = buttons[args.__hasReduce ? 1 : 0]; + const hasReduceFrequency = args.specify?.ratio !== 0; + await expect(buttons).toHaveLength(hasReduceFrequency ? 2 : 1); + const reduce = hasReduceFrequency ? buttons[0] : null; + const back = buttons[hasReduceFrequency ? 1 : 0]; if (reduce) { await expect(reduce).toBeInTheDocument(); await expect(reduce).toHaveTextContent(i18n.ts._ad.reduceFrequencyOfThisAd); @@ -80,15 +82,16 @@ const common = { lock = undefined; } }, - */ args: { prefer: [], specify: { id: 'someadid', - radio: 1, + ratio: 1, url: '#test', + place: '', + imageUrl: '', + dayOfWeek: 7, }, - __hasReduce: true, }, parameters: { layout: 'centered', @@ -138,6 +141,5 @@ export const ZeroRatio = { ...Square.args.specify, ratio: 0, }, - __hasReduce: false, }, } satisfies StoryObj; diff --git a/packages/frontend/src/components/global/MkAvatar.stories.impl.ts b/packages/frontend/src/components/global/MkAvatar.stories.impl.ts index 933754ec4c..9d2de9f0be 100644 --- a/packages/frontend/src/components/global/MkAvatar.stories.impl.ts +++ b/packages/frontend/src/components/global/MkAvatar.stories.impl.ts @@ -33,7 +33,7 @@ const common = { }, decorators: [ (Story, context) => ({ - // eslint-disable-next-line quotes + // @ts-expect-error size is for test template: `
`, }), ], @@ -45,6 +45,7 @@ export const ProfilePage = { ...common, args: { ...common.args, + // @ts-expect-error size is for test size: 120, indicator: true, }, diff --git a/packages/frontend/src/components/global/MkCondensedLine.stories.impl.ts b/packages/frontend/src/components/global/MkCondensedLine.stories.impl.ts index e4e90cddd5..e15dcba760 100644 --- a/packages/frontend/src/components/global/MkCondensedLine.stories.impl.ts +++ b/packages/frontend/src/components/global/MkCondensedLine.stories.impl.ts @@ -28,6 +28,7 @@ export const Default = { }; }, args: { + // @ts-expect-error text is for test text: 'This is a condensed line.', }, parameters: { @@ -41,4 +42,5 @@ export const ContainerIs100px = { template: '
', }), ], + // @ts-expect-error text is for test } satisfies StoryObj; diff --git a/packages/frontend/src/components/global/MkError.stories.meta.ts b/packages/frontend/src/components/global/MkError.stories.meta.ts index 1abbc56f50..cd7fada189 100644 --- a/packages/frontend/src/components/global/MkError.stories.meta.ts +++ b/packages/frontend/src/components/global/MkError.stories.meta.ts @@ -3,8 +3,11 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { Meta } from '@storybook/vue3'; +import MkError from './MkError.vue'; + export const argTypes = { - retry: { + onRetry: { action: 'retry', }, -}; +} satisfies Meta['argTypes']; diff --git a/packages/frontend/src/components/global/MkPageHeader.stories.impl.ts b/packages/frontend/src/components/global/MkPageHeader.stories.impl.ts index eb74e874dd..1d079edd2c 100644 --- a/packages/frontend/src/components/global/MkPageHeader.stories.impl.ts +++ b/packages/frontend/src/components/global/MkPageHeader.stories.impl.ts @@ -33,7 +33,6 @@ export const Empty = { await waitFor(async () => await wait); }, args: { - static: true, tabs: [], }, parameters: { @@ -71,8 +70,8 @@ export const IconOnly = { ...Icon.args, tabs: [ { - ...Icon.args.tabs[0], - title: undefined, + key: Icon.args.tabs[0].key, + icon: Icon.args.tabs[0].icon, iconOnly: true, }, ], diff --git a/packages/frontend/src/components/global/MkPageHeader.tabs.vue b/packages/frontend/src/components/global/MkPageHeader.tabs.vue index e93b09721a..fcc46cc345 100644 --- a/packages/frontend/src/components/global/MkPageHeader.tabs.vue +++ b/packages/frontend/src/components/global/MkPageHeader.tabs.vue @@ -38,7 +38,6 @@ SPDX-License-Identifier: AGPL-3.0-only