Create your own UI/UX library.
yarn commit- run commit wizard, all commits should be created with this commandyarn start- start dev server onhttp://localhost:8000yarn story-build- build storybookyarn lint- runs eslint, prettier and stylelint and fixes source code
Script yarn build runs build scripts from ./build directory.
Env variables:
DEBUG=woly:*- shows debug linesNEXT=true- publishes version to thenextnpm dist-tagDRY_RUN=true- runsnpm publishwith--dry-runparameterPACKAGE=name- build onlynamepackagePACKAGES=first,second- build onlyfirstandsecondpackages
Example:
DEBUG=woly:* NEXT=true DRY_RUN=true yarn build- Review draft release in GitHub
- Set version from draft release to versions.json
- Commit and push
- At the Publish Package CI press "Run workflow"
- Set "yes" for packages that need to be published, and press "Run workflow"
Screenshot testing is the automated process of comparing the visible output of a component against a baseline image. It helps to prevent unwanted visual changes and to make sure that it works as intended.
All examples are based on the woly package.
Below you can see recommended folder structure. Test files MUST be inside __screenshot-test__ directory, which directly inside the component's folder.
button/
ββ __screenshot-test__
β ββ config.json
β ββ index.tsx
ββ index.tsx
ββ usage.mdx
ββ specification.mdx
config.jsβ config file for test-runner, which describes how to capture component's statesindex.tsxβ a React component, that renders all combinations of the tested component viaStateMapcomponent fromlib/state-map
| Name | Type | Default value | Description |
|---|---|---|---|
name |
string |
null |
Component's name |
selector |
string |
null |
Selector, which test-runner uses to find a component in a test page |
screenshotSize |
{ width: number, height: number} |
null |
Screenshot's size. Final snapshot's width will be equal to states amount x screenshot's width |
states |
State[] |
[] |
States to capture |
A state can be described by a simple string like a static | press | hover | focus. The test-runner will bring a component to that state.
However, when it comes to more complex components, we need a flexible way to reproduce a state we want to capture. In this case, pass an object instead of a string with the structure described below:
| Name | Type | Default value | Description |
|---|---|---|---|
name |
string |
null |
State's name |
actions |
function |
null |
An async function that will bring component to the desired state |
A actions function gets the following parameters:
elβ the actual component (see methods)elWrapperβ a component's wrapper. The test-runner makes a screenshot of this element. Has the same methods aseldisabledβ if a component is disabled, someplaywrightmethods can't be triggered on component and it will throw an error (see actionability checks). Check for this boolean before invocing methods likefillon input elementspageβ a test page (see methods)
Attention: When using a function for describing a state, be aware that test-runner unable to reset the state after capturing it, a state will be just passed unchanged to the next one. If you don't want this behavior, you can return a reset function from state that will be called before moving to the next state.
For example:
{
name: 'text-filled',
actions: async ({ el, elWrapper, disabled, page }) => {
const input = await el.$('input[type="password"]');
await input.type('qwerty');
// reset function
return async () => {
if(!disabled) {
await input.fill(''); // remove the text in the input
}
await elWrapper.focus(); // remove the focus from the input
}
},
},The example is based on the Button component.
import React from 'react';
import { IconPlus } from 'static/icons';
import { Sizes, StateMap, Priorities } from 'dev/state-map';
import { block } from 'dev/block';
import { Button } from '../index';
export const ButtonStateMap = () => {
return (
<StateMap
// all `buttons` props variations
propVariations={{
disabled: [true, false],
icon: [true, false],
outlined: [true, false],
size: Sizes,
priority: Priorities,
}}
// prop, by wich the variants will be grouped
groupByProp="variant"
render={({ size, icon, priority, outlined, disabled }) => {
const SizeBlock = block[size];
return (
<SizeBlock>
<Button
// provide classname for component and match it
// in configs 'selector' option
className="button-st"
text="button"
icon={icon ? <IconPlus /> : undefined}
priority={priority}
outlined={outlined}
disabled={disabled}
/>
</SizeBlock>
);
}}
/>
);
};
For local testing, run the command yarn test:screenshot
Env variables:
DEBUG=screenshot*- shows debug linesINCLUDE=first,second- include only componentsfirstandsecondto testing. Has higher priority thanEXCLUDE.EXCLUDE=first,second- exclude componentsfirstandsecondfrom testing
If you want to manually send snapshots to percy, you must pass PERCY_TOKEN env variable with a token as the value (grab it in the persy.io's Project settings section) and run the test by the command yarn percy:ci, e.g. PERCY_TOKEN=***** yarn percy:ci.