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
diff --git a/README.md b/README.md
index 16ae2fdc..fa04bd35 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,19 @@
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)
+ - [Resources](#resources)
+
## Testing Web Applications
## Objectives
@@ -56,3 +69,13 @@ 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](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/)
+ - [Regex](https://regexr.com)
+ - [jest](https://jestjs.io/docs/en/expect.html)
\ No newline at end of file
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 5f80a897..fe32dde3 100644
--- a/src/components/ContactForm.test.js
+++ b/src/components/ContactForm.test.js
@@ -4,38 +4,155 @@ 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');
});
-test('renders the contact form header', ()=> {
-
+
+it('renders without errors', ()=>{
+ render();
});
-test('renders ONE error message if user enters less then 5 characters into firstname.', async () => {
-
+test('2 renders the contact form header', ()=> {
+ render();
+ const header = screen.queryByText(/contact form/i);
+ 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 THREE error messages if user enters no values into any fields.', 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 ONE error message if user enters a valid first name and last name but no email.', 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 "email must be a valid email address" if an invalid email is entered', 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 "lastName is a required field" if an last name is not entered and the submit button is clicked', 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 all firstName, lastName and email text when submitted. Does NOT render message if message is not submitted.', 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();
});
-test('renders all fields text when all fields are 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('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';
+
+ 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');
-});
\ No newline at end of file
+ expect(firstNameDisplay).toBeVisible();
+ expect(screen.getByText(/mansfield/i)).toBeTruthy();
+ screen.getByText(/mansfield/i);
+ });
\ No newline at end of file