Skip to content

Commit 488ce05

Browse files
authored
Merge pull request #172 from argos-ci/improve-viewports
fix(storybook): improve storybook viewports doc
2 parents 2f251c9 + ca45502 commit 488ce05

File tree

2 files changed

+81
-37
lines changed

2 files changed

+81
-37
lines changed

docs/guides/storybook-story-modes.mdx

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ A mode is a preset that configures various Storybook globals. For instance, you
2525

2626
## Setting up globals & addons
2727

28-
Before you define any modes, make sure you’ve configured the relevant Storybook addons in your .storybook/preview.js (or .storybook/preview.ts) file. Examples include:
28+
Before you define any modes, make sure you’ve configured the relevant Storybook addons in your `.storybook/preview.ts` (or `.js`) file. Examples include:
2929

3030
- [`@storybook/addon-viewport`](https://www.npmjs.com/package/@storybook/addon-viewport) for screen sizes
3131
- [`@storybook/addon-themes`](https://www.npmjs.com/package/@storybook/addon-themes) for light/dark themes
@@ -34,8 +34,7 @@ Before you define any modes, make sure you’ve configured the relevant Storyboo
3434

3535
These addons utilize Storybook “globals” and “decorators” under the hood. Argos modes simply manipulate those globals at test time to generate multiple snapshots of the same story.
3636

37-
```ts
38-
// .storybook/preview.js
37+
```ts title=".storybook/preview.ts"
3938
import { withThemeByClassName } from "@storybook/addon-themes";
4039
import "../src/styles.css";
4140

@@ -76,11 +75,9 @@ export default preview;
7675

7776
## Defining modes
7877

79-
Create a `.storybook/modes.js` (or `.ts`) file that exports an object where each key is a mode name and each value is a set of overrides for the Storybook globals. For example:
80-
81-
```ts
82-
// .storybook/modes.js
78+
Create a `.storybook/modes.ts` (or `.js`) file that exports an object where each key is a mode name and each value is a set of overrides for the Storybook globals. For example:
8379

80+
```ts title=".storybook/modes.ts"
8481
export const allModes = {
8582
dark: {
8683
backgrounds: { value: "#1A1A1A" },
@@ -106,17 +103,18 @@ Each object can include as many or as few globals as you need. If a mode doesn
106103

107104
## Applying modes
108105

109-
Attach modes to any level of your Storybook: globally in `.storybook/preview.js`, at the component (default export) level, or in an individual story’s parameters. Argos merges all modes defined up the chain.
106+
Attach modes to any level of your Storybook: globally in `.storybook/preview.ts` (or `.js`), at the component (default export) level, or in an individual story’s parameters. Argos merges all modes defined up the chain.
110107

111108
### Basic usage in a story file
112109

113-
```ts
114-
// src/components/ProductCard/ProductCard.stories.js
110+
```ts title="ProductCard.stories.ts"
111+
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
112+
import type { Meta, StoryObj } from "@storybook/your-framework";
115113

116114
import { ProductCard } from "./ProductCard";
117115
import { allModes } from "../../../.storybook/modes";
118116

119-
export default {
117+
const meta = {
120118
title: "Components/ProductCard",
121119
component: ProductCard,
122120
parameters: {
@@ -128,18 +126,19 @@ export default {
128126
},
129127
},
130128
},
131-
};
129+
} satisfies Meta<typeof ProductCard>;
130+
131+
export default meta;
132+
type Story = StoryObj<typeof meta>;
132133

133-
// Story #1
134-
export const DefaultView = {
134+
export const DefaultView: Story = {
135135
args: {
136136
productName: "Coffee Beans",
137137
price: 9.99,
138138
},
139139
};
140140

141-
// Story #2
142-
export const SoldOutView = {
141+
export const SoldOutView: Story = {
143142
args: {
144143
productName: "Coffee Beans",
145144
price: 9.99,
@@ -152,12 +151,11 @@ In this example, Argos will generate two snapshots for each story (DefaultView a
152151

153152
## Combining modes from multiple levels
154153

155-
You can add modes in your .storybook/preview.js at the project level, then define additional modes in a story file. Argos “stacks” these modes, creating a snapshot for every combination.
154+
You can add modes in your `.storybook/preview.ts` (or `.js`) at the project level, then define additional modes in a story file. Argos “stacks” these modes, creating a snapshot for every combination.
156155

157156
### Project-level modes
158157

159-
```ts
160-
// .storybook/preview.js
158+
```ts title=".storybook/modes.ts"
161159
import { allModes } from "./modes";
162160

163161
const preview = {
@@ -175,12 +173,13 @@ export default preview;
175173

176174
### Component-level modes
177175

178-
```ts
179-
// ProductCard.stories.js
176+
```ts title="ProductCard.stories.ts"
177+
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
178+
import type { Meta, StoryObj } from "@storybook/your-framework";
180179
import { ProductCard } from "./ProductCard";
181180
import { allModes } from "../../../.storybook/modes";
182181

183-
export default {
182+
const meta = {
184183
title: "Components/ProductCard",
185184
component: ProductCard,
186185
parameters: {
@@ -190,25 +189,28 @@ export default {
190189
},
191190
},
192191
},
193-
};
192+
} satisfies Meta<typeof ProductCard>;
193+
194+
export default meta;
195+
type Story = StoryObj<typeof meta>;
194196

195-
// Single story for brevity
196-
export const Basic = {
197+
export const Basic: Story = {
197198
args: {
198199
/* ... */
199200
},
200201
};
201202
```
202203

203-
When Argos runs, it will generate snapshots for each mode defined at the project level and the component level. So for Basic, you get “light mobile” (from `preview.js`) plus “dark widescreen” (from the component’s parameter).
204+
When Argos runs, it will generate snapshots for each mode defined at the project level and the component level. So for Basic, you get “light mobile” (from `preview.ts`) plus “dark widescreen” (from the component’s parameter).
204205

205206
## Excluding or disabling modes
206207

207208
Sometimes you want to turn off a certain higher-level mode for a specific story. You can do this by passing a disable property:
208209

209-
```ts
210-
// ProductCard.stories.js
211-
export const SpecialCard = {
210+
```ts title="ProductCard.stories.ts"
211+
// ...
212+
213+
export const SpecialCard: Story = {
212214
args: {
213215
/* ... */
214216
},

docs/guides/viewports.mdx

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,36 @@ title: Responsive Viewports
55

66
# Configuring Responsive Viewports
77

8-
Master responsive testing with Argos: Easily configure viewports for Playwright, Cypress, and Puppeteer, ensuring your app looks great on any device.
8+
Argos lets you capture the same page at multiple breakpoints with a single test. Configure viewports once and get consistent responsive coverage across Playwright, Cypress and Puppeteer.
99

1010
## Prerequisites
1111

1212
This advanced feature integrates smoothly with [Playwright](/playwright), [Cypress](/cypress), and [Puppeteer](/puppeteer) to enhance your testing capabilities.
1313

14+
This feature works seamlessly with [Playwright](/playwright), [Cypress](/cypress) and [Puppeteer](/puppeteer).
15+
16+
:::note
17+
18+
If you use Storybook, see the dedicated guide on [Storybook modes](/storybook-story-modes).
19+
20+
:::
21+
1422
## Viewport Configuration
1523

16-
Adjust the `argosScreenshot()` command in your test scripts to capture responsive screenshots. You can specify exact dimensions or use device presets to mimic real-world scenarios:
24+
Pass a viewports array to `argosScreenshot()` to generate screenshots for each dimension or preset you define. You can mix explicit sizes and device presets.
1725

1826
```js
1927
await argosScreenshot(..., {
2028
viewports: [
21-
"iphone-4", // Use device preset
22-
{ width: 800, height: 600 }, // Specify dimensions directly
23-
{ preset: "ipad-2", orientation: "landscape" }, // Device preset with orientation
29+
"iphone-4",
30+
{ width: 800, height: 600 },
31+
{ preset: "ipad-2", orientation: "landscape" },
2432
],
2533
});
2634
```
2735

2836
## Available Presets
2937

30-
List of available device presets with their respective dimensions:
31-
3238
| Preset | Width (px) | Height (px) |
3339
| ------------- | ---------- | ----------- |
3440
| macbook-16 | 1536 | 960 |
@@ -52,4 +58,40 @@ List of available device presets with their respective dimensions:
5258

5359
## Troubleshooting and Best Practices
5460

55-
To ensure accurate rendering, always set the viewport size with `page.setViewportSize()` before navigating to the target page, as many sites do not dynamically adapt to changes in viewport size after the page has loaded. For comprehensive testing, consider running your tests across all intended viewports to validate responsive behavior across the board.
61+
Many sites compute layout at load time and will not adapt cleanly if the viewport changes later. If you notice issues, you may want to run your test suite entirely for each viewport instead of changing the viewport before taking each screenshot.
62+
63+
For example, in Playwright you can create a separate browser context for each viewport size.
64+
65+
```ts title="playrwight.config.ts"
66+
import { defineConfig, devices } from "@playwright/test";
67+
68+
export default defineConfig({
69+
projects: [
70+
{
71+
name: "chromium-mobile",
72+
use: {
73+
...devices["Desktop Chrome"],
74+
channel: "chrome",
75+
},
76+
},
77+
{
78+
name: "chromium-mobile",
79+
use: {
80+
...devices["Desktop Chrome"],
81+
channel: "chrome",
82+
viewport: { width: 402, height: 874 }, // iPhone 7 viewport
83+
},
84+
},
85+
],
86+
});
87+
```
88+
89+
You can also run `page.setViewportSize()` before navigating to the page to ensure the layout is computed correctly.
90+
91+
```ts
92+
await page.setViewportSize({
93+
width: 640,
94+
height: 480,
95+
});
96+
await page.goto("https://example.com");
97+
```

0 commit comments

Comments
 (0)