test(storybook): add some tests
This commit is contained in:
parent
ca5b6e26ae
commit
d387ad34c6
|
|
@ -8,6 +8,7 @@
|
||||||
import { StoryObj } from '@storybook/vue3';
|
import { StoryObj } from '@storybook/vue3';
|
||||||
import { HttpResponse, http } from 'msw';
|
import { HttpResponse, http } from 'msw';
|
||||||
import { action } from '@storybook/addon-actions';
|
import { action } from '@storybook/addon-actions';
|
||||||
|
import { expect, userEvent, within } from '@storybook/test';
|
||||||
import { commonHandlers } from '../../.storybook/mocks.js';
|
import { commonHandlers } from '../../.storybook/mocks.js';
|
||||||
import MkClickerGame from './MkClickerGame.vue';
|
import MkClickerGame from './MkClickerGame.vue';
|
||||||
export const Default = {
|
export const Default = {
|
||||||
|
|
@ -31,6 +32,16 @@ export const Default = {
|
||||||
template: '<MkClickerGame v-bind="props" />',
|
template: '<MkClickerGame v-bind="props" />',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
async play({ canvasElement }) {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
const count = canvas.getByTestId('count');
|
||||||
|
// NOTE: flaky なので N/A も通しておく
|
||||||
|
await expect(count).toHaveTextContent(/^(0|N\/A)$/);
|
||||||
|
const buttonElement = canvas.getByRole<HTMLButtonElement>('button');
|
||||||
|
await userEvent.click(buttonElement);
|
||||||
|
// FIXME: flaky
|
||||||
|
// await expect(count).toHaveTextContent('1');
|
||||||
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
layout: 'centered',
|
layout: 'centered',
|
||||||
msw: {
|
msw: {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div>
|
<div>
|
||||||
<div v-if="game.ready" :class="$style.game">
|
<div v-if="game.ready" :class="$style.game">
|
||||||
<div :class="$style.cps" class="">{{ number(cps) }}cps</div>
|
<div :class="$style.cps" class="">{{ number(cps) }}cps</div>
|
||||||
<div :class="$style.count" class=""><i class="ti ti-cookie" style="font-size: 70%;"></i> {{ number(cookies) }}</div>
|
<div :class="$style.count" class="" data-testid="count"><i class="ti ti-cookie" style="font-size: 70%;"></i> {{ number(cookies) }}</div>
|
||||||
<button v-click-anime class="_button" @click="onClick">
|
<button v-click-anime class="_button" @click="onClick">
|
||||||
<img src="/client-assets/cookie.png" :class="$style.img">
|
<img src="/client-assets/cookie.png" :class="$style.img">
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,18 @@
|
||||||
/* eslint-disable import/no-default-export */
|
/* eslint-disable import/no-default-export */
|
||||||
import { StoryObj } from '@storybook/vue3';
|
import { StoryObj } from '@storybook/vue3';
|
||||||
import { action } from '@storybook/addon-actions';
|
import { action } from '@storybook/addon-actions';
|
||||||
|
import { expect, userEvent, within } from '@storybook/test';
|
||||||
|
import { file } from '../../.storybook/fakes.js';
|
||||||
import MkCwButton from './MkCwButton.vue';
|
import MkCwButton from './MkCwButton.vue';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
|
import { semaphore } from '@/scripts/test-utils.js';
|
||||||
|
|
||||||
|
function sleep(ms: number) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
const s = semaphore();
|
||||||
|
|
||||||
export const Default = {
|
export const Default = {
|
||||||
render(args) {
|
render(args) {
|
||||||
return {
|
return {
|
||||||
|
|
@ -42,7 +53,33 @@ export const Default = {
|
||||||
args: {
|
args: {
|
||||||
text: 'Some CW content',
|
text: 'Some CW content',
|
||||||
},
|
},
|
||||||
|
async play({ canvasElement }) {
|
||||||
|
await s.acquire();
|
||||||
|
await sleep(1000);
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
const buttonElement = canvas.getByRole<HTMLButtonElement>('button');
|
||||||
|
await expect(buttonElement).toHaveTextContent(i18n.ts._cw.show);
|
||||||
|
await expect(buttonElement).toHaveTextContent(i18n.tsx._cw.chars({ count: 15 }));
|
||||||
|
await userEvent.click(buttonElement);
|
||||||
|
await expect(buttonElement).toHaveTextContent(i18n.ts._cw.hide);
|
||||||
|
await userEvent.click(buttonElement);
|
||||||
|
s.release();
|
||||||
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
layout: 'centered',
|
layout: 'centered',
|
||||||
},
|
},
|
||||||
} satisfies StoryObj<typeof MkCwButton>;
|
} satisfies StoryObj<typeof MkCwButton>;
|
||||||
|
export const IncludesTextAndDriveFile = {
|
||||||
|
...Default,
|
||||||
|
args: {
|
||||||
|
text: 'Some CW content',
|
||||||
|
files: [file()],
|
||||||
|
},
|
||||||
|
async play({ canvasElement }) {
|
||||||
|
const canvas = within(canvasElement);
|
||||||
|
const buttonElement = canvas.getByRole<HTMLButtonElement>('button');
|
||||||
|
await expect(buttonElement).toHaveTextContent(i18n.tsx._cw.chars({ count: 15 }));
|
||||||
|
await expect(buttonElement).toHaveTextContent(' / ');
|
||||||
|
await expect(buttonElement).toHaveTextContent(i18n.tsx._cw.files({ count: 1 }));
|
||||||
|
},
|
||||||
|
} satisfies StoryObj<typeof MkCwButton>;
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,13 @@ export async function tick(): Promise<void> {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
await new Promise((globalThis.requestIdleCallback ?? setTimeout) as never);
|
await new Promise((globalThis.requestIdleCallback ?? setTimeout) as never);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://github.com/misskey-dev/misskey/issues/11267
|
||||||
|
*/
|
||||||
|
export function semaphore(counter = 0, waiting: (() => void)[] = []) {
|
||||||
|
return {
|
||||||
|
acquire: () => ++counter > 1 && new Promise<void>(resolve => waiting.push(resolve)),
|
||||||
|
release: () => --counter && waiting.pop()?.(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue