diff --git a/app/pages/sign-in.js b/app/pages/sign-in.js index de2f811f0..5caf2d21a 100644 --- a/app/pages/sign-in.js +++ b/app/pages/sign-in.js @@ -1,24 +1,59 @@ -import React from 'react'; -import { ErrorMessage, Field, Form, Formik } from 'formik'; +import React, { useEffect, useState } from 'react'; +import { ErrorMessage, Field, Form, FormikProvider, useFormik } from 'formik'; import * as Yup from 'yup'; -const SignIn = () => ( -
-

Sign In

- - { - await new Promise(r => setTimeout(r, 500)); - alert(JSON.stringify(values, null, 2)); - }} - > - {formik => ( +const SignIn = () => { + const [errorLog, setErrorLog] = useState([]); + + const formik = useFormik({ + validateOnMount: true, + initialValues: { username: '', password: '' }, + validationSchema: Yup.object().shape({ + username: Yup.string().required('Required'), + password: Yup.string().required('Required'), + }), + onSubmit: async values => { + await new Promise(r => setTimeout(r, 500)); + alert(JSON.stringify(values, null, 2)); + }, + }); + + useEffect(() => { + if (formik.errors.username && formik.touched.username) { + setErrorLog(logs => [ + ...logs, + { + name: 'username', + value: formik.values.username, + error: formik.errors.username, + }, + ]); + } + + if (formik.errors.password && formik.touched.password) { + setErrorLog(logs => [ + ...logs, + { + name: 'password', + value: formik.values.password, + error: formik.errors.password, + }, + ]); + } + }, [ + formik.values.username, + formik.errors.username, + formik.touched.username, + formik.values.password, + formik.errors.password, + formik.touched.password, + ]); + + return ( +
+

Sign In

+ +
@@ -33,10 +68,12 @@ const SignIn = () => ( + +
{JSON.stringify(errorLog, null, 2)}
- )} - -
-); +
+
+ ); +}; export default SignIn; diff --git a/cypress/integration/basic.spec.ts b/cypress/integration/basic.spec.ts index ec5e2df2e..618eabfe8 100644 --- a/cypress/integration/basic.spec.ts +++ b/cypress/integration/basic.spec.ts @@ -15,6 +15,24 @@ describe('basic validation', () => { cy.get('#renderCounter').contains('0'); }); + it('should validate show errors on blur', () => { + cy.visit('http://localhost:3000/sign-in'); + + cy.get('input[name="username"]') + .type('john') + .blur() + .siblings('p') + .should('have.length', 0); + + cy.get('input[name="password"]') + .type('123') + .blur() + .siblings('p') + .should('have.length', 0); + + cy.get('#error-log').should('have.text', '[]'); + }); + it('should validate autofill', () => { // React overrides `input.value` setters, so we have to call // native input setter