Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lk/merge lesson #748

Merged
merged 24 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8727f93
Enhance Outlet content and add example without using it
niksseif Aug 10, 2023
8ff9712
Move Router prework lesson to fe curriculum
Sep 21, 2023
7a188e4
Add intro to router lesson to curriculum site
Sep 21, 2023
afa943e
Add 2024 calendar and remove 2022 calendar
kaylagordon Sep 21, 2023
0370587
Update format of calendar page
kaylagordon Sep 21, 2023
8284f41
Align links to intro to router lesson
Sep 21, 2023
900ca83
Merge pull request #739 from turingschool/intro-to-router-preowkr
hfaerber Sep 21, 2023
dbde234
Remove broken community button
kaylagordon Sep 21, 2023
f7a277b
Merge branch 'gh-pages' of github.com:turingschool/front-end-curricul…
kaylagordon Sep 21, 2023
d21921a
Add note about project font.
niksseif Sep 21, 2023
b48a5c5
Merge pull request #735 from turingschool/Nik-FP-New
niksseif Sep 21, 2023
86f04fd
update mod 2 instructors
CassandraGoose Sep 29, 2023
63b54e0
Add resources to Cypress lesson
Oct 13, 2023
63842de
Merge pull request #744 from turingschool/cypress-add-tips
hfaerber Oct 13, 2023
d27b5df
Combine two user flows
Oct 16, 2023
c366b2a
Update initial examples
Oct 16, 2023
c4609af
Pull important notes out of solution drop down
Oct 16, 2023
10e7529
Merge pull request #745 from turingschool/cypress-update
hfaerber Oct 17, 2023
cbf7560
Make gsm option only redux
Oct 17, 2023
4b392af
Remove old links from public api list
Oct 17, 2023
8c0a821
Merge pull request #746 from turingschool/remove-context-from-stretch
hfaerber Oct 17, 2023
8ffc689
Bring back museum link
Oct 17, 2023
1d08d67
Merge pull request #747 from turingschool/remove-context-from-stretch
hfaerber Oct 17, 2023
f897917
Add a note about VSCode's new merge conflict GUI
letakeane Oct 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ <h2>Daily Turing</h2>
<a class="btn btn-dark" href="/lessons">Lessons</a>
<a class="btn btn-dark" href="/projects">Projects</a>
<a class="btn btn-dark" href="https://careerdev.turing.edu">Professional Development</a>
<a class="btn btn-dark" target="_blank" rel="noopener" href="https://community.turing.edu/">Community</a>
<!-- broken link -->
<!-- <a class="btn btn-dark" target="_blank" rel="noopener" href="https://community.turing.edu/">Community</a> -->
<a class="btn btn-dark" href="/mental_health">Mental Health Resources</a>
</section>

Expand Down
7 changes: 3 additions & 4 deletions lessons/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,8 @@ <h2>Module 2 Lessons</h2>
<p class="mod-description">Module 2 focuses on fundamental JavaScript concepts, popular patterns for writing and organizing front-end code, and learning new tools and workflows to help improve the development process for more complex applications. Projects will reinforce lesson concepts by emphasizing Object-Oriented Programming, Test-Driven Development and heavy data manipulation.</p>

<h3>Instructors</h3>
<li>Jeremiah Black</li>
<li>Scott Ertmer</li>
<li>Robbie Jaeger (Anchor)</li>
<li>Jeremiah Black</li>

<h3>Resources</h3>
<ul>
Expand Down Expand Up @@ -234,14 +233,14 @@ <h3>React</h3>
<h3>React Router</h3>

<ul>

<li class="lesson"><a href="module-3/intro-to-router-self-study-lesson.html">Intro To Router Self Study Lesson</a></li>
<li class="lesson"><a href="module-3/react-router-v6.html">React Router 6</a></li>
</ul>

<h3>Advanced React</h3>

<ul>
<li class="lesson"><a href = "module-3/react-class-components-prework.html"> React Class component legacy code prework</a></li>
<li class="lesson"><a href = "module-3/react-class-components-prework.md"> React Class component legacy code prework</a></li>
<li class="lesson"><a href="module-3/react-class-components.html">Intro to Class Components</a></li>
<!-- <li class="lesson"><a href="module-3/data-visualization-with-react.html">Data Visualization with React</a></li> -->
</ul>
Expand Down
8 changes: 8 additions & 0 deletions lessons/module-1/git-merge-conflicts.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ When you run into the merge conflict on GitHub, go ahead and create the PR, then

GitHub offers instructions for how to resolve a merge conflict through the command line (using your text editor). They are essentially the same steps as outlined above. Test out these instructions when you encounter a merge conflict.

<section class="note">
### Note

In VS Code, you may see a button that reads "Resolve in Merge Editor". This opens a GUI much like the GitHub merge conflict editor demonstrated briefly in the video at the beginning of the lesson.

You can experiment with that editor if you like, but for the same reason we don't advise that you become solely dependent on using the GitHub GUI for merge conflicts, don't become dependent on the VS Code GUI for merge conflicts.
</section>

## Best practices to avoid merge conflicts
- Do your edits/work on branches. Do not edit the main branch directly. Do not push to main.
- If you accidentally start coding on main, don't worry! You can create a new branch and it will bring those edits to the new branch.
Expand Down
88 changes: 55 additions & 33 deletions lessons/module-3/intro-to-cypress-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,16 +230,27 @@ This is great and all but let's think about what we actually need to test. Reme

Now that we've identified some user flows, let's get to testing (finally)! First, let's focus on this user flow:

**As a user, I should be able to visit `http://localhost:3000` and see a title & form displayed.**
**1a. As a user, I should be able to visit `http://localhost:3000` and see a title & form displayed.**

* Write a test that asserts that a user can visit `http://localhost:3000` using the [visit](https://docs.cypress.io/api/commands/visit.html#Syntax) command.
* In the same `it` block, check to make sure that our site can [get](https://docs.cypress.io/api/commands/get.html#Syntax){:target='blank'} a form and that it [contains](https://docs.cypress.io/api/commands/contains.html){:target='blank'} the correct text on the page!
* In the same `it` block, check to make sure that our site [contains](https://docs.cypress.io/api/commands/contains.html){:target='blank'} the correct title text.
* Then, check to make sure our site can [get](https://docs.cypress.io/api/commands/get.html#Syntax){:target='blank'} the displayed form and that it [contains](https://docs.cypress.io/api/commands/contains.html){:target='blank'} the correct header text within the form.
* Run your test to ensure no errors so far. Take note of any errors that you get in the `Test Body` of the **Command Log**.

**1b. Adding onto the same flow, as a user, I can select the inputs, fill them out, as confirm that each input's value matches what I typed.**
* In the same `it` block, get the *email* input field, [type](https://docs.cypress.io/api/commands/type.html){:target='blank'} "[email protected]" into that field. This is the user action we're simulating in Cypress. Now we need to assert against the results of that action.
* Assert that the email input field [should](https://docs.cypress.io/api/commands/should.html#Syntax){:target='blank'} have the same value as whatever you typed into it.
* Get the *password* input field, type "keane20" into that field.
* Assert that the email input field [should](https://docs.cypress.io/api/commands/should.html#Syntax){:target='blank'} have the same value as whatever you typed into it.
* Take note of any errors that you get in the `Test Body` of the **Command Log**.

This test might feel a bit unneccesary and overly simple - but it's valuable. Thinking about controlled forms, what are we actually testing here?
<!-- Here is a link to [commonly used assertions](https://docs.cypress.io/guides/references/assertions.html#Common-Assertions) in Cypress! -->

<section class="note">
### Note
### Note - Your React app must be running in order for Cypress to work

You might notice that your test fails when trying to load your site. This is because Cypress is actually trying to visit your page, but your server is not running. Make sure your React server is running in a separate tab on your terminal! You do not need to have the API server running, though.
If your test fails when trying to load your site, this might be because Cypress is actually trying to visit your page, but your server is not running. Make sure your React App server is running in a separate tab on your terminal! You do not need to have the API server running, though.
</section>

<section class="answer">
Expand All @@ -249,71 +260,67 @@ You might notice that your test fails when trying to load your site. This is bec
// login_spec.js

describe('Feedback Loop login', () => {
it('Should be able to visit the page and render the correct elements', () => {
it('Should be able to visit page, render correct elements, and hold values in inputs', () => {
cy.visit('http://localhost:3000')
.contains('Feedback Loop')
.get('form')
.contains('Please Sign In');
.get('form').contains('h2', "Please Sign In")
.get("input[name='email']").type("[email protected]").should('have.value', '[email protected]')
.get("input[name='password']").type("keane20").should('have.value', 'keane20')
});
});
```

Note that we can chain multiple methods to make multiple assertions!
</section>

Before starting our next test, let's add in the following block:
Before we continue, let's add in the following block:

```js
beforeEach(() => {
cy.visit('http://localhost:3000');
});
```

This helps to ensure that we start anew before each test. A [best practice](https://docs.cypress.io/guides/references/best-practices.html#Having-tests-rely-on-the-state-of-previous-tests){:target='blank'} is that tests should always be able to run independently from one another and *still pass*.
This helps to ensure that we start anew before each test. A [best practice](https://docs.cypress.io/guides/references/best-practices.html#Having-tests-rely-on-the-state-of-previous-tests){:target='blank'} is that tests should always be able to run independently from one another and *still pass*. A **common pitfall** is adding code to the beforeEach that isn't needed by every `it` block. If it's not used by every single `it` block, it doesn't belong in the beforeEach - put it directly into `it` blocks that needed it instead.

**User flow to test:** I can select different inputs and fill them out.
<section class="note">
### Did You Know?

* Experiment with [type](https://docs.cypress.io/api/commands/type.html){:target='blank'} and [should](https://docs.cypress.io/api/commands/should.html#Syntax){:target='blank'} as you write a test that selects the `Email` and `Password` inputs and fills them with the corresponding values, `[email protected]` and `keane20`. Assert that they have the correct values.
In the test runner, you can actually hit `command + option + i` to open up your DevTools! Instead of looking at your code, use your DevTools to find the necessary elements you need to query.

Here is a link to [commonly used assertions](https://docs.cypress.io/guides/references/assertions.html#Common-Assertions) in Cypress!
To add the React Dev Tools to your cypress browser window, take a look at [this blog post](https://www.cypress.io/blog/2020/01/07/how-to-load-the-react-devtools-extension-in-cypress/){:target='blank'}.
</section>

**User flow to test:** I will receive an error message when I click the Submit button without filling out both inputs.
**2. User flow to test:** I will receive an error message when I click the Submit button without filling out both inputs.

* Write another test that asserts an error message is displayed when the Submit button is [clicked](https://docs.cypress.io/api/commands/click.html){:target='blank'} without filling both inputs.
* Write another test - in a new `it` block - that asserts an error message is displayed when the Submit button is [clicked](https://docs.cypress.io/api/commands/click.html){:target='blank'} without filling both inputs.

<section class="note">
### Did You Know?
### Note - Never end a test on a "click"

In the test runner, you can actually hit `command + option + i` to open up your DevTools! Instead of looking at your code, use your DevTools to find the necessary elements you need to query.
Why? Because to test any user flow, we need to walk Cypress through simulating some user action. *Then*, we assert against whatever the user should see on the DOM as a *result* of that action. The `click` is the action, so its only getting us halfway there. We always need to add assertions after.

To add the React Dev Tools to your cypress browser window, take a look at [this blog post](https://www.cypress.io/blog/2020/01/07/how-to-load-the-react-devtools-extension-in-cypress/){:target='blank'}.
Here is a link to [commonly used assertions](https://docs.cypress.io/guides/references/assertions.html#Common-Assertions) in Cypress!
</section>

<section class="answer">
### Solutions

```js
it('should be able to select the email and password inputs and fill them with the corresponding values', () => {
cy.get('input[type="email"]')
.type('[email protected]')
.should('have.value', '[email protected]')
.get('input[type="password"]')
.type('keane20')
.should('have.value', 'keane20')
})

it('should display an error message when a user clicks the Submit button without filling both inputs', () => {
cy.get('button').click()
cy.contains('Please fill out both inputs')
cy.get('button').click() //This is the user action we're simulating.
cy.get('p').contains('Please fill out both inputs.') //This is where we're asserting against whatever we expect as a result of that user action.
});
```
</section>



### Writing tests involving network requests

**User Story:** As a user, I can fill out the `email` and `password` inputs and click the Submit button and be directed to a different URL.
**User Story:** As a user, I can correctly fill out the `email` and `password` inputs and click the Submit button and be directed to a different URL.

* This builds off of what we have done previously, however we now want to test that when we log in successfully and visit the new url `http://localhost:3000/dashboard`. It's okay if the page doesn't display all of the data on the next page, just assert that the url has updated.
* This builds off of what we have done previously, however we now want to test that when we log in successfully, our app takes us to a new url - `http://localhost:3000/dashboard`. It's okay if the page doesn't display all of the data on the next page, just assert that the url has updated for now.

<section class="note">
### Note
Expand Down Expand Up @@ -347,11 +354,13 @@ For now (and throughout Mod 3), we will instead use [stubbing](https://docs.cypr
.url().should('include', '/dashboard')
});
```
</section>

Note that we are just intercepting the `POST` request for logging in and mocking out what the expected response would look like. Our dashboard is blank because we haven't mocked out the other network requests; this is something we'll test later on in our dashboard spec.
Note that in our solution we are just intercepting the `POST` request for logging in and mocking out what the expected response would look like. Our dashboard is blank because we haven't mocked out the other network requests; this is something we'll test later on in our dashboard spec.

All we need to worry about is that our URL has updated to the page we expect to view when we are logged in.
</section>
*How can we tell which network requests have and have not been properly stubbed?*

For now, all we are asserting is that our URL has updated to the page we expect to view when we are logged in. To thoroughly test this user flow, we'd also want to assert for all the elements and data we expect to see on the DOM.

### Testing the Sad Path to a Network Request

Expand Down Expand Up @@ -618,3 +627,16 @@ The [documentation](https://docs.cypress.io/api/api/table-of-contents.html){:tar
* What is Cypress and how is it different from other testing frameworks you've used in the past?
* Should you include tests that utilize the API (end-to-end) or should you stub the network requests? Is there an argument for both?
</section>

### Building From Here
Remember, this lesson and it's activities are just an *introduction* to the world of testing with Cypress. We've only scratched the surface. In order to build your knowledge, fluency and skill to the level needed to succeed in Mod 3 and beyond, you will need to spend significant time in the Cypress documentation and getting your hands dirty with practice. In project-based learning, your projects will be your primary platform for learning. The feedback you get from that project work is what will help guide you towards further research and really help you level up your skill.

## Resources

- The official [Cypress Documentation](https://docs.cypress.io/guides/overview/why-cypress)
- Pay particular attention to the following pages in the docs:
- [Best Practices](https://docs.cypress.io/guides/references/best-practices)
- [aliasing](https://docs.cypress.io/guides/core-concepts/variables-and-aliases)
- [waiting](https://docs.cypress.io/guides/guides/network-requests#Waiting)

- Heather's [Cypress Tips & Tricks](https://turingschool.notion.site/Cypress-Tips-Tricks-8565977029cf48faa6003046c148a048?pvs=4)
42 changes: 42 additions & 0 deletions lessons/module-3/intro-to-router-self-study-lesson.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: React Router v6
length: 1.5 hours
tags: React, Router
module: 3
---

# Intro to Router Self Study Prework Lesson
This self-study lesson requires you to work through the questions below using the React Router (v6) documentation and other resources. This self study lesson is required prework prior to our live React Router lesson.

## Instructions
1. Copy these questions to a gist, notion or other online document.
2. Go through the listed readings and answer associated questions.
3. Submit your completed document to your instructors via this [submission form.](https://forms.gle/Jwsu6SHCvYtK21N1A)

## Questions / Readings

### Router Overview
React Router is a library that allows us to make our single page React applications mimic the behavior of multipage apps.
It provides the ability to use browser history, allowing users to navigate with forward / back buttons and bookmark links to specific views of the app. Most modern sites use some form of routing. React Router exposes this functionality through a series of components. Let's start by looking at the overall structure of an app using router:

**Read through [this guide](https://reactrouter.com/en/main/start/overview).**

#### Router Components
React Router provides a series of helpful components that allow our apps to use routing. These can be split into roughly 3 categories:
- Routers
- Route Matcher
- Route Changers

#### Routers
Any code that uses a React-Router-provided component must be wrapped in a _router component_. There are lots of router components we can use, but we'll focus on one in particular. Let's look into the docs to learn more.

1. What is a `<BrowserRouter />`?

#### Route Matchers
2. What does the `<Route />` component do?
3. What does the `<Routes />` component do?
4. What does the `<Outlet />` component do?

#### Route Changers
9. What does the `<Link />` component do? How does a user interact with it?
10. What does the `<NavLink />` component do? How does a user interact with it?
Loading