рдкрд╣рд▓реЗ, рд╕рд░реВ рдХреЛ рдПрдХ e2e рдкрд░реАрдХреНрд╖рдг рдЙрдкрдХрд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рдерд╛ред рдПрдХ рдРрд╕реЗ рд╡рд┐рд╖рдп рдореЗрдВ рд╕рд╛рдордиреЗ рдХреЗ рдЗрдВрдЬреАрдирд┐рдпрд░реЛрдВ рдХреА рдмрдврд╝рддреА рд░реБрдЪрд┐ рдХрд╛ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рджрд┐рд▓рдЪрд╕реНрдк рдерд╛ рдЬрд┐рд╕рдореЗрдВ рд╕реЗрд▓реЗрдирд┐рдпрдо рдиреЗ рдЕрдкрдиреЗ рдкреВрд░реЗ рдЬреАрд╡рди рдкрд░ рд╢рд╛рд╕рди рдХрд┐рдпрд╛ рдерд╛ред рдЙрд╕ рд╕рдордп, рд╕рд░реВ рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡реАрдбрд┐рдпреЛ рдпрд╛ рд▓реЗрдЦ рдбреЗрдЯрд╛ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд▓рд┐рдП рдПрдкреАрдЖрдИ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд░реВрдк рд╕реЗ рдЪрдпрдирд┐рдд рд╕рд╛рдЗрдЯ рдФрд░ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдпреЛрдЧреНрдп рдЪрд╛рдкрд▓реВрд╕реА рд╕рдореАрдХреНрд╖рд╛рдУрдВ рдХреЗ рдЖрд╕рдкрд╛рд╕ рднрдЯрдХрдиреЗ рддрдХ рд╕реАрдорд┐рдд рдерд╛ред
рд╣рдо рдореЗрдВ рд╕реЗ рдХрдИ рд▓реЛрдЧреЛрдВ рдиреЗ рд╕реНрдЯреЛрд░реАрдмреБрдХ / рд╕реНрдЯрд╛рдЗрд▓рдЧрд╛рдЗрдбрд┐рд╕реНрдЯ / рдбреЙрдХреНрдЬрд╝ рдЬреИрд╕реЗ рд╡рд╛рддрд╛рд╡рд░рдг рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рдЕрд▓рдЧрд╛рд╡ рдореЗрдВ рдШрдЯрдХреЛрдВ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рд╕рд░реВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рд╣реИред рдПрдХ рдЕрдЪреНрдЫрд╛ рдЙрджрд╛рд╣рд░рдг рд╣реИ рд╕реНрдЯреЗрдлрд╛рдиреЛ рдореИрдЧреА рдХрд╛ рд▓реЗрдЦ " рд╕рд╛рдЗрд░рд╕ рдПрдВрдб рд╕реНрдЯреЛрд░реАрдмреБрдХ рдХреЗ рд╕рд╛рде рдПрдХ рдЖрднрд╛рд╕реА рд╕реВрдЪреА рдШрдЯрдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг" ред рдпрд╣ рдПрдХ рд╕реНрдЯреЛрд░реАрдмреБрдХ рд╕реНрдЯреЛрд░реА рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдореЗрдВ рдПрдХ рдШрдЯрдХ рд░рдЦреЗрдВ рдФрд░ рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рдбреЗрдЯрд╛ рдореЗрдВ рдбрд╛рд▓реЗрдВ рдЬреЛ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЕрдЪреНрдЫрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдЯреЗрд╕реНрдЯ рд╕реНрдЯреЛрд░реАрдмреБрдХ рдФрд░ рд╕рд░реВ рдХреЗ рдмреАрдЪ рдлрдЯрд╛ рд╣реБрдЖ рд╣реИред рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдИ рдШрдЯрдХ рд╣реИрдВ, рддреЛ рдРрд╕реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдкрдврд╝рдирд╛ рдФрд░ рдмрдирд╛рдП рд░рдЦрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛрдЧрд╛ред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдпрд╣ рджрд┐рдЦрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ рдЖрдЧреЗ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рд╕рд░реВ рдореЗрдВ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╕реЗ рдЕрдзрд┐рдХрддрдо рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдПред рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдХреГрдкрдпрд╛ рдкрддреЗ рдкрд░ рд╕реНрд░реЛрдд рдХреЛрдб рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ рдФрд░ npm i рдФрд░ npm рд░рди рдЯреЗрд╕реНрдЯ рдХрдорд╛рдВрдб рдЪрд▓рд╛рдПрдВ ред
tl; рдбреЙ:
- рдЖрдк рдПрдХ рдХрд┐рддрд╛рдм рдореЗрдВ рдПрдХ рд▓рд┐рдВрдХ рдХреЛ рд╕рд╛рдЗрдкреНрд░реЗрд╕ рджреНрд╡рд╛рд░рд╛ рдЕрдкрдиреА рд╕рдВрдкреВрд░реНрдгрддрд╛ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдЯреЛрд░реАрдмреБрдХ рд╕реНрдЯреЛрд░реА рд╕реЗ рдПрдХ рдШрдЯрдХ рдореЗрдВ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ (рдкрд░реАрдХреНрд╖рдг рддрд░реНрдХ рдХреЛ рдХрдИ рднрд╛рдЧреЛрдВ рдореЗрдВ рддреЛрдбрд╝реЗ рдмрд┐рдирд╛)ред
- рд╕рд░реВ рд╣рдорд╛рд░реА рдЯреАрдо рдХреЗ рд▓рд┐рдП рдЗрддрдирд╛ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд▓рдЧ рд░рд╣рд╛ рдерд╛ рдХрд┐ рд╣рдордиреЗ рдпреВрдЖрдИ рдШрдЯрдХреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реБрдб рдХреЗ рдиреАрдЪреЗ рдЬреЗрдПрд╕-рдбреЛрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рддреНрдпрд╛рдЧ рджрд┐рдпрд╛ред
рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдирд┐рд░реВрдкрдг
, Datepicker . , .
Storybook
Storybook , тАФ Story . , Story DOM-. тАФ , Cypress .
import React from 'react';
import Datepicker from './Datepicker.jsx';
export default {
component: Datepicker,
title: 'Datepicker',
};
export const emptyStory = () => {
window.Datepicker = Datepicker;
return (
<div id="component-test-mount-point"></div>
)
};
Storybook. Cypress.
Cypress
-. , :
import React from 'react';
import ReactDOM from 'react-dom';
context('<Datepicker />', () => {
it('renders text field.', () => { });
it('renders desired placeholder text.', () => { });
it('renders chosen date.', () => { });
it('opens calendar after clicking on text field.', () => { });
})
. . Storybook. Story, "Open canvas in new tab" sidebar. URL Cypress:
const rootToMountSelector = '#component-test-mount-point';
before(() => {
cy.visit('http://localhost:12345/iframe.html?id=datepicker--empty-story');
cy.get(rootToMountSelector);
});
, div id=component-test-mount-point. , . :
afterEach(() => {
cy.document()
.then((doc) => {
ReactDOM.unmountComponentAtNode(doc.querySelector(rootToMountSelector));
});
});
. , :
const selectors = {
innerInput: '.react-datepicker__input-container input',
};
it('renders text field.', () => {
cy.window().then((win) => {
ReactDOM.render(
<win.Datepicker />,
win.document.querySelector(rootToMountSelector)
);
});
cy
.get(selectors.innerInput)
.should('be.visible');
});
? props. . . тАФ Cypress!
,
, props.
<Popup /> c props "showed". "showed" true, <Popup /> . "showed" c true false, <Popup /> .
?
, React - .
state. state boolean, "showed" props.
let setPopupTestWrapperState = null;
const PopupTestWrapper = ({ showed, win }) => {
const [isShown, setState] = React.useState(showed);
setPopupTestWrapperState = setState;
return <win.Popup showed={isShown} />
}
, :
it('becomes hidden after being shown when showed=false passed.', () => {
cy.window().then((win) => {
ReactDOM.render(
<PopupTestWrapper
showed={true}
win={win}
/>,
win.document.querySelector(rootToMountSelector)
);
});
cy.then(() => { setPopupTestWrapperState(false); })
cy
.get(selectors.popupWindow)
.should('not.be.visible');
});
: hook setState , class.
, , . , - -.
Cypress . ref . , ref state .
<Popup /> , ( ). :
it('closes via method call.', () => {
let popup = React.createRef();
cy.window().then((win) => {
ReactDOM.render(
<win.Popup
showed={true}
ref={popup}
/>,
win.document.querySelector(rootToMountSelector)
);
});
cy.then(() => { popup.current.hide(); })
cy
.get(selectors.popupWindow)
.should('not.be.visible');
})
:
Storybook:
- Storybook Stories React .
- .
- Story window ( Cypress).
- Story , ( ).
- .
: Storybook . Stories .
Cypress:
- JavaScript .
- Stories, .
- (, ).
- .
- UI .
, . , , .
js-dom . ?
- Js-dom , . DOM .
- js-dom . .
- -, CSS z-index? Cypress, .
- - . ?
?
тАФ !
тАФ .
"" - react-lifecycle тАФ тАж . . , ? , ?
cypress-react-unit-test? Storybook?
тАФ . Storybook, Cypress, ..
рд▓реЗрдХрд┐рди рдЕрдм рдЗрд╕ рдЙрдкрдХрд░рдг рдореЗрдВ рдХрдИ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ рдЬреЛ рдЗрд╕реЗ рдЪрд▓рд╛рдиреЗ рдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреВрд░реНрдг рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВред
рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ Gleb Bahmutov рдФрд░ Cypress рдХреА рдЯреАрдо рдЗрди рдХрдард┐рдирд╛рдЗрдпреЛрдВ рд╕реЗ рдирд┐рдкрдЯреЗрдЧреАред
рдкреБрдирд╢реНрдЪ: рдореЗрд░реА рд░рд╛рдп рдФрд░ рдореЗрд░реЗ рд╕рд╣рдХрд░реНрдорд┐рдпреЛрдВ рдХреА рд░рд╛рдп рдЗрд╕ рдмрд╛рдд рд╕реЗ рд╕рд╣рдордд рд╣реИ рдХрд┐ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣рдореЗрдВ рдЬреЗрдПрд╕-рдбреЛрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рдПрдХрд╛рдзрд┐рдХрд╛рд░ рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рддреБрдо рдЙрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рд╕реЛрдЪрддреЗ рд╣реЛ?