рд╕рд░реВ + рдХрд╣рд╛рдиреА рдХреА рдХрд┐рддрд╛рдмред рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ, рдбреЗрдЯрд╛ рдФрд░ рдШрдЯрдХ рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд╛ рднрдВрдбрд╛рд░рдг

рдкрд╣рд▓реЗ, рд╕рд░реВ рдХреЛ рдПрдХ 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 = () => {
    // Reference to retrieve it in Cypress during the test
    window.Datepicker = Datepicker;

    // Just a mount point
    return (
        <div id="component-test-mount-point"></div>
    )
};

Storybook. Cypress.


Cypress


-. , :


/// <reference types="cypress" />

import React from 'react';
import ReactDOM from 'react-dom';

/**
 * <Datepicker />
 * * renders text field.
 * * renders desired placeholder text.
 * * renders chosen date.
 * * opens calendar after clicking on text field.
 */

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.', () => {
    // arrange
    cy.window().then((win) => {
        // initial state - popup is visible
        ReactDOM.render(
            <PopupTestWrapper
                showed={true}
                win={win}
            />,
            win.document.querySelector(rootToMountSelector)
        );
    });

    // act
    cy.then(() => { setPopupTestWrapperState(false); })

    // assert
    cy
        .get(selectors.popupWindow)
        .should('not.be.visible');
});

: hook setState , class.


, , . , - -.


Cypress . ref . , ref state .


<Popup /> , ( ). :


it('closes via method call.', () => {
    // arrange
    let popup = React.createRef();
    cy.window().then((win) => {
        // initial state - popup is visible
        ReactDOM.render(
            <win.Popup
                showed={true}
                ref={popup}
            />,
            win.document.querySelector(rootToMountSelector)
        );
    });

    // act
    cy.then(() => { popup.current.hide(); })

    // assert
    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 рдХреА рдЯреАрдо рдЗрди рдХрдард┐рдирд╛рдЗрдпреЛрдВ рд╕реЗ рдирд┐рдкрдЯреЗрдЧреАред


рдкреБрдирд╢реНрдЪ: рдореЗрд░реА рд░рд╛рдп рдФрд░ рдореЗрд░реЗ рд╕рд╣рдХрд░реНрдорд┐рдпреЛрдВ рдХреА рд░рд╛рдп рдЗрд╕ рдмрд╛рдд рд╕реЗ рд╕рд╣рдордд рд╣реИ рдХрд┐ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣рдореЗрдВ рдЬреЗрдПрд╕-рдбреЛрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рдПрдХрд╛рдзрд┐рдХрд╛рд░ рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рддреБрдо рдЙрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рд╕реЛрдЪрддреЗ рд╣реЛ?


All Articles