From 159614a6e718aa12bd858beee7aae23b28885ef6 Mon Sep 17 00:00:00 2001 From: Rick Date: Tue, 3 Aug 2021 19:27:46 -0500 Subject: [PATCH 01/14] Rick Mansfield's Push/Pull Trail Testin Web Apps --- .vscode/settings.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..85f78eb4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "workbench.colorCustomizations": { + "activityBar.background": "#142F4C", + "titleBar.activeBackground": "#1B426A", + "titleBar.activeForeground": "#F8FAFD" + } +} \ No newline at end of file From 2c1091a92c05b3d06f14368514c67617915a511a Mon Sep 17 00:00:00 2001 From: Rick Date: Tue, 3 Aug 2021 19:29:29 -0500 Subject: [PATCH 02/14] Added TOC in ReadME.md --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 16ae2fdc..fbd01104 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,18 @@ This module explored the basics of the react-testing library and ideas behind the integration testing methodology. In this project you will practice how to build tests that follow the arrange-act-assert model, different methods of querying for DOM elements in a test, the use of different expect types and using async/await to test for changes in state. +- [Integration Testing React Module Project : Contact Form - Testing](#integration-testing-react-module-project--contact-form---testing) + - [Testing Web Applications](#testing-web-applications) + - [Objectives](#objectives) + - [Introduction](#introduction) + - [Instructions](#instructions) + - [Task 1: Project Set Up](#task-1-project-set-up) + - [Task 2: Project Requirements](#task-2-project-requirements) + - [Test Brainstorming](#test-brainstorming) + - [Complete a case that tests if:](#complete-a-case-that-tests-if) + - [Stretch goals](#stretch-goals) + - [Rick Mansfield's PUll Request Link](#rick-mansfields-pull-request-link) + ## Testing Web Applications ## Objectives @@ -56,3 +68,8 @@ As a developer, you will be writing tests for every component. As we've learned, - Look at your test cases in Understanding-questions and see if there are any that you have not completed. - From the this list or from your own mind, add in at least one more new testcase. - There is alot of state management within our component in this project! See if you can separate the form and error validation code into their own hooks. + + +## Rick Mansfield's PUll Request Link + +- [Link for Convenience]() \ No newline at end of file From 25731addf581e43dd18e9843cd4bcc4e7c2c5d10 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 10:49:37 -0500 Subject: [PATCH 03/14] Sanity test and test one complete --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fbd01104..0e045e33 100644 --- a/README.md +++ b/README.md @@ -72,4 +72,4 @@ As a developer, you will be writing tests for every component. As we've learned, ## Rick Mansfield's PUll Request Link -- [Link for Convenience]() \ No newline at end of file +- [Link for Convenience](https://github.com/LambdaSchool/web-module-project-testing-web-apps/pull/71) \ No newline at end of file From 612e851221aa5d9f556f48751b4835918729e6a6 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 10:50:43 -0500 Subject: [PATCH 04/14] Complete Test two "header" --- src/components/ContactForm.test.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/ContactForm.test.js b/src/components/ContactForm.test.js index 5f80a897..86a4c9d1 100644 --- a/src/components/ContactForm.test.js +++ b/src/components/ContactForm.test.js @@ -4,11 +4,20 @@ import userEvent from '@testing-library/user-event'; import ContactForm from './ContactForm'; -test('renders without errors', ()=>{ - +test("does the test 1", ()=>{ + // throw new Error("This is an error") + console.log('doing a sanity test 1'); +}); + + +it('renders without errors', ()=>{ + render(); }); test('renders the contact form header', ()=> { + render(); + const header = screen.queryByText(/contact form/i); + expect(header).toBeVisible(); }); From e9368d5de3516132c04d4d8adf122c6c38424e43 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 14:12:22 -0500 Subject: [PATCH 05/14] Add Testing Library Cheatsheet to readme.md --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e045e33..d175dd91 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ This module explored the basics of the react-testing library and ideas behind th - [Complete a case that tests if:](#complete-a-case-that-tests-if) - [Stretch goals](#stretch-goals) - [Rick Mansfield's PUll Request Link](#rick-mansfields-pull-request-link) + - [Resources](#resources) ## Testing Web Applications @@ -72,4 +73,8 @@ As a developer, you will be writing tests for every component. As we've learned, ## Rick Mansfield's PUll Request Link -- [Link for Convenience](https://github.com/LambdaSchool/web-module-project-testing-web-apps/pull/71) \ No newline at end of file +- [Link for Convenience](https://github.com/LambdaSchool/web-module-project-testing-web-apps/pull/71) + + +## Resources + - [React Testing Library Cheatsheet](https://testing-library.com/docs/react-testing-library/cheatsheet/) \ No newline at end of file From 3366a5c898cb160cda2629fe03caffb7e0ddb9be Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 17:45:57 -0500 Subject: [PATCH 06/14] refactor test 2 --- src/components/ContactForm.test.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/components/ContactForm.test.js b/src/components/ContactForm.test.js index 86a4c9d1..49db43ec 100644 --- a/src/components/ContactForm.test.js +++ b/src/components/ContactForm.test.js @@ -14,13 +14,21 @@ it('renders without errors', ()=>{ render(); }); -test('renders the contact form header', ()=> { +test('2 renders the contact form header', ()=> { render(); const header = screen.queryByText(/contact form/i); - expect(header).toBeVisible(); - + console.log(header); + expect(header).toBeInTheDocument();//can use either + expect(header).toBeVisible();//can use any of these + expect(header).toHaveTextContent(/contact form/i); + expect(header).toBeTruthy(); + expect(header).not.toBeFalsy(); +//another example to just have plenty of options + const h1 = screen.queryByTestId('testh1'); + expect(h1).toBeInTheDocument();//can also tag with an id and use any of these }); + test('renders ONE error message if user enters less then 5 characters into firstname.', async () => { }); From 38f0dc6dcbeb2ae4c3af36c08befa4a7e8c23021 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 17:46:17 -0500 Subject: [PATCH 07/14] add to read me too --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d175dd91..fa04bd35 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ As a developer, you will be writing tests for every component. As we've learned, - [Link for Convenience](https://github.com/LambdaSchool/web-module-project-testing-web-apps/pull/71) - ## Resources - - [React Testing Library Cheatsheet](https://testing-library.com/docs/react-testing-library/cheatsheet/) \ No newline at end of file + - [React Testing Library Cheatsheet](https://testing-library.com/docs/react-testing-library/cheatsheet/) + - [Regex](https://regexr.com) + - [jest](https://jestjs.io/docs/en/expect.html) \ No newline at end of file From c7b525411eed2ea865f9094ea8bcbef63c42a614 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 17:47:04 -0500 Subject: [PATCH 08/14] Complete test 3 --- src/components/ContactForm.test.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/ContactForm.test.js b/src/components/ContactForm.test.js index 49db43ec..61bf5f35 100644 --- a/src/components/ContactForm.test.js +++ b/src/components/ContactForm.test.js @@ -29,10 +29,17 @@ test('2 renders the contact form header', ()=> { }); -test('renders ONE error message if user enters less then 5 characters into firstname.', async () => { - +test('3 renders ONE error message if user enters less then 5 characters into firstname.', async () => { + render(); + const firstName = "Ric"; + const firstNameInput = screen.getByLabelText(/first name/i); + userEvent.type(firstNameInput, firstName); + const errorMessage = screen.queryAllByText(/error/i); + expect(errorMessage).toHaveLength(1); + expect(errorMessage).toBeTruthy();//same thing }); + test('renders THREE error messages if user enters no values into any fields.', async () => { }); From d1f3f64f952549c33c143be793be078148baf334 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 17:47:36 -0500 Subject: [PATCH 09/14] complete test 4 --- src/components/ContactForm.test.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/ContactForm.test.js b/src/components/ContactForm.test.js index 61bf5f35..6a70384e 100644 --- a/src/components/ContactForm.test.js +++ b/src/components/ContactForm.test.js @@ -40,8 +40,13 @@ test('3 renders ONE error message if user enters less then 5 characters into fir }); -test('renders THREE error messages if user enters no values into any fields.', async () => { - +test('4 renders THREE error messages if user enters no values into any fields.', async () => { + render(); + const submitButton = screen.getByRole('button');//arrange + userEvent.click(submitButton); + const errorMessages = screen.queryAllByTestId(/error/i); + expect(errorMessages).toHaveLength(3); + }); test('renders ONE error message if user enters a valid first name and last name but no email.', async () => { From 6d14093fefd0a85e2745f7800edef84ea03cbeb1 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 17:48:43 -0500 Subject: [PATCH 10/14] Complete test 5 --- src/components/ContactForm.test.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/components/ContactForm.test.js b/src/components/ContactForm.test.js index 6a70384e..05029717 100644 --- a/src/components/ContactForm.test.js +++ b/src/components/ContactForm.test.js @@ -49,8 +49,26 @@ test('4 renders THREE error messages if user enters no values into any fields.', }); -test('renders ONE error message if user enters a valid first name and last name but no email.', async () => { - +test('5 renders ONE error message if user enters a valid first name and last name but no email.', async () => { + render(); + //enters first name + const firstName = "Ricster"; + const firstNameInput = screen.getByLabelText(/first name/i); + userEvent.type(firstNameInput, firstName); + //enters last name + const lastName = "Mansfield"; + const lastNameInput = screen.getByLabelText(/Last Name/i); + userEvent.type(lastNameInput, lastName); + //uses submit button before entering email + const button = screen.getByRole('button'); + userEvent.click(button); + //should see error for email + const errorMessages = screen.queryAllByText(/error/i); + expect(errorMessages).toHaveLength(1); + //alternative check for email error message using preestablished variable from test 4 + const emailErrorMessage = screen.queryAllByTestId(/error/i); + expect(emailErrorMessage).toHaveLength(1); + }); test('renders "email must be a valid email address" if an invalid email is entered', async () => { From adecaa67b7d4c306364d084aeba97314c0b15b9d Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 17:58:19 -0500 Subject: [PATCH 11/14] Completed test 6 --- src/components/ContactForm.test.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/ContactForm.test.js b/src/components/ContactForm.test.js index 05029717..d2b28311 100644 --- a/src/components/ContactForm.test.js +++ b/src/components/ContactForm.test.js @@ -71,8 +71,19 @@ test('5 renders ONE error message if user enters a valid first name and last nam }); -test('renders "email must be a valid email address" if an invalid email is entered', async () => { - +test('6 renders "email must be a valid email address" if an invalid email is entered', async () => { + render(); + //Arrange = create bad email and retrieve email input field + const email = 'badEmail'; + const emailInput = screen.getByLabelText(/email/i); + //Act = input bad email into field just like a user might do & use submitt button + userEvent.type(emailInput, email); + const submitButton = screen.getByRole('button');//arrange + userEvent.click(submitButton); + //Assert = expect to get error message for email + const errorMessage = screen.queryByText(/email must be a valid email address/i); + expect(errorMessage).toBeVisible(); + }); test('renders "lastName is a required field" if an last name is not entered and the submit button is clicked', async () => { From bdb8c4b3706626364a56b54850be3ce7ed90f103 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 18:08:38 -0500 Subject: [PATCH 12/14] completed test 7 --- src/components/ContactForm.test.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/ContactForm.test.js b/src/components/ContactForm.test.js index d2b28311..d6473595 100644 --- a/src/components/ContactForm.test.js +++ b/src/components/ContactForm.test.js @@ -86,7 +86,15 @@ test('6 renders "email must be a valid email address" if an invalid email is ent }); -test('renders "lastName is a required field" if an last name is not entered and the submit button is clicked', async () => { +test('7 renders "lastName is a required field" if an last name is not entered and the submit button is clicked', async () => { + render(); + //ARRANGE - The message prints upon using submit without doing anything So We only need to screen for the button + const submitButton = screen.getByRole('button'); + //ACT - user then clicks the button + userEvent.click(submitButton); + //ASSERT - error message for last name is expected + const errorMessage = screen.queryByText(/lastName is a required field/i); + expect(errorMessage).toBeVisible(); }); From 3fa158662b4e2ca1d4b7bfd8a9b0eed900060de2 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 18:43:08 -0500 Subject: [PATCH 13/14] Completed test 8 passing --- src/components/ContactForm.test.js | 32 ++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/components/ContactForm.test.js b/src/components/ContactForm.test.js index d6473595..2ff6125f 100644 --- a/src/components/ContactForm.test.js +++ b/src/components/ContactForm.test.js @@ -98,9 +98,37 @@ test('7 renders "lastName is a required field" if an last name is not entered an }); -test('renders all firstName, lastName and email text when submitted. Does NOT render message if message is not submitted.', async () => { +test('8 renders all firstName, lastName and email text when submitted. Does NOT render message if message is not submitted.', async () => { -}); + render(); + //Arrange Need good first, last and email and screen for each field + const firstName = 'William'; + const lastName = 'Mansfield'; + const email = 'RicksMyCodeGuy@gmail.com'; + + const firstNameInput = screen.getByLabelText(/first name/i); + const lastNameInput = screen.getByLabelText(/Last Name/i); + const emailInput = screen.getByLabelText(/email/i); + //Act user inputs each and clicks submit button no message until after clicked + userEvent.type(firstNameInput, firstName); + userEvent.type(lastNameInput, lastName); + userEvent.type(emailInput, email); + + const messageDiv = screen.queryByText(/you submitted/i); + expect(messageDiv).toBeFalsy();//starts falsy + + const button = screen.getByRole('button'); + userEvent.click(button); + //Assert - should get affimative You Submitted: card back with all details rendered back + // expect(messageDiv).toBeTruthy();//ends truthy couldn't get this to work. seeing help + + const firstNameDisplay = screen.queryByTestId('firstnameDisplay'); + const lastNameDisplay = screen.queryByTestId('lastnameDisplay'); + const emailDisplay = screen.queryByTestId('emailDisplay'); + + expect(firstNameDisplay).toBeVisible(); + expect(lastNameDisplay).toBeVisible(); + expect(emailDisplay).toBeVisible(); test('renders all fields text when all fields are submitted.', async () => { From 02121d10626199bdf2d3d83c28893d5de74e1738 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 4 Aug 2021 18:55:14 -0500 Subject: [PATCH 14/14] Completed test 9 passing add notes.md to explain --- notes.md | 42 ++++++++++++++++++++++++++++++ src/components/ContactForm.test.js | 27 +++++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 notes.md diff --git a/notes.md b/notes.md new file mode 100644 index 00000000..63e83cec --- /dev/null +++ b/notes.md @@ -0,0 +1,42 @@ +this file contains notes from the video regarding options on waiting for a promist to be completed. Use the preview for an easier read. +```javascript +test("User can add multiple animals", async () => { + // Arrange: render & grab the elements we need + render(); + + const speciesInput = screen.getByLabelText(/species/i); + const ageInput = screen.getByLabelText(/age/i); + const notesInput = screen.getByLabelText(/notes/i); + const submitButton = screen.getByRole('button', { name: /submit/i }); + + // Act: fill out the form and click the button (simulating user behavior with userEvent) + userEvent.type(speciesInput, "Deer"); + userEvent.type(ageInput, "98"); + userEvent.type(notesInput, "I'm the first animal and I love 98 Degrees"); + userEvent.click(submitButton); + + // Intermediate assertion: now we should have just deer, no llamas + expect(screen.getByText(/deer/i)).toBeInTheDocument(); + expect(screen.queryByText(/llama/i)).toEqual(null); + + //async assertion: + + // if you are changing state you may want to "wait" for the change... such as a change handler + //THE PROMISE WAY ... + // const newItemPromise = screen.findByText("deer"); + // console.log(newItemPromise); + // newItemPromise.then(newItem=>{ + // console.log(newItem); + // expect(newItem).toBeInTheDocument(); + // }); + + //THE AWAIT WAY + // 1) + // const newItem = await screen.findByText("deer");//did you put "async" in first line? + // console.log(newItem); + // 2) + await waitFor(() => { + const newItem = screen.findByText("deer"); + expect(newItem).toBeInTheDocument(); + }); + ``` diff --git a/src/components/ContactForm.test.js b/src/components/ContactForm.test.js index 2ff6125f..fe32dde3 100644 --- a/src/components/ContactForm.test.js +++ b/src/components/ContactForm.test.js @@ -130,6 +130,29 @@ test('8 renders all firstName, lastName and email text when submitted. Does NOT expect(lastNameDisplay).toBeVisible(); expect(emailDisplay).toBeVisible(); -test('renders all fields text when all fields are submitted.', async () => { + test('9 renders all fields text when all fields are submitted.', async () => { + render(); + //Arranged need good first, last, email, scan for each field + const firstName = 'Wiliam'; + const lastName = 'Mansfield'; + const email = 'RicksMyCodeGuy@gmail.com'; -}); \ No newline at end of file + const firstNameInput = screen.getByLabelText(/first name/i); + const lastNameInput = screen.getByLabelText(/last name/i); + const emailInput = screen.getByLabelText(/email/i); + + //ACT - user enters each as arranged above and uses submit button + userEvent.type(firstNameInput, firstName); + userEvent.type(lastNameInput, lastName); + userEvent.type(emailInput, email); + + const button = screen.getByRole('button'); + userEvent.click(button); + + //Assert - must utilize a delay method | Per Warrens video the "Await" vs the "Promise" is shorter. I've included the notes from class an an extra file called notes.md attached next to the readme.md file. + const firstNameDisplay = await screen.findByTestId('firstnameDisplay'); + + expect(firstNameDisplay).toBeVisible(); + expect(screen.getByText(/mansfield/i)).toBeTruthy(); + screen.getByText(/mansfield/i); + }); \ No newline at end of file