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

Add React router tests #430

Merged
merged 4 commits into from
Oct 29, 2024
Merged

Conversation

gabalafou
Copy link
Contributor

@gabalafou gabalafou commented Oct 17, 2024

Note to reviewer: before reviewing this PR, check out the comments on gabalafou#1.

This PR contains the tests for #429.

It is a separate PR because it makes significant changes to the React app code.

I believe that these changes are not only necessary to enable these tests but that they also fix a long-standing bug that I guess we did not even realize that we had.

The bug is that we say in our docs that the UI app can be configured "at runtime, using condaStoreConfig." But before this PR, the app code would choose the build-time over run-time config. It would read the config sources in the following order:

  1. build-time value of environment variable
  2. run-time value of condaStoreConfig dictionary in browser

But that seemed backward and was preventing me from taking the testing approach in this PR, so I swapped the order:

  1. run time condaStoreConfig
  2. build time environment variable

Description

This pull request:

  • Swaps the order in which config variables are read. First it reads from condaStoreConfig, then from process.env (environment variables). Important note: environment variables can only be read at build time.
  • Adds a new Playwright test file for router testing
  • Adds an HTML file that allows Playwright to load the app with memory routing configured
  • Configures Webpack to output the HTML file

Pull request checklist

  • Did you test this change locally?
  • Did you update the documentation (if required)?
  • Did you add/update relevant tests for this change (if required)?

@peytondmurray peytondmurray self-requested a review October 17, 2024 15:24
@peytondmurray peytondmurray self-assigned this Oct 17, 2024
@trallard trallard added type: enhancement 💅🏼 New feature or request area: testing ✅ Design of the test infrastructure and everything related labels Oct 21, 2024
@trallard
Copy link
Collaborator

@gabalafou this has some conflicts, can you please fix the branch?

@peytondmurray could you please review this PR?

Copy link
Contributor

@peytondmurray peytondmurray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, really nice - just one question about error codes. Thanks for following up about this, and for the bug fix on top!

src/preferences.tsx Outdated Show resolved Hide resolved
def test_browser_router_404_not_found(page: Page, test_config):
"""With browser router, an unknown route should result in a 404 not found error
"""
page.goto(test_config["base_url"] + "/this-is-not-an-app-route")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, I tried looking at the Response object returned by page.goto and found that the response code was 200 (OK). Do we expect it to be 404 here? It might be a more robust way of checking the right response, maybe in addition to get_by_text('404').

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, hm, yeah, that is confusing.

I have actually forgotten best practices for this.

I recently created a related conda-store server issue about creating a catch-all route that returns the UI app instead of a 404, if no other route is matched.

I will have to do some research, but I think that ultimately if we want an actual HTTP 404 status code, we will have to define the UI app routes in both the client-side and server-side code.

The only reason these nonsense routes, such as /foo-bar, return the UI app with a 200, by the way, is because of the --history-api-fallback Webpack dev server flag passed to the package.json start script:

"start:ui": "REACT_APP_VERSION=$npm_package_version webpack server --history-api-fallback",

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the error code itself is intended behavior of --history-api-fallback. Is that good/what we want? Seems like invalid routes should return error codes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm? I'm not sure I follow. In the example you pasted above, the --history-api-fallback flag is precisely why /foo/bar returns 200 (with the app bundle) instead of a 404.

I did some web searching and I discovered that one solution (that doesn't require us to find a way to share routes between the front end and the back end) is to do a JavaScript redirect to a 404/not-found page when the user goes to an unknown route. Here's how that would work, step by step:

  1. User visits /foo/bar
  2. Server returns React app with 200 status code
  3. React app boots up in the browser, doesn't recognize the /foo/bar route, executes client-side redirect JavaScript redirect like so: window.location = "/not-found"
  4. Server returns a 404 page for the /not-found route. (Actually, it could maybe should return the React app at /not-found, but with a 404 status code instead of 200.)

Does that make sense? It's a little less than ideal. But the ideal solution requires us to either duplicate or share the React app routes between both the front-end and back-end codebases.

Copy link
Contributor Author

@gabalafou gabalafou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @peytondmurray! I responded to your question and also raised a question about how to handle .env booleans.

src/preferences.tsx Outdated Show resolved Hide resolved
def test_browser_router_404_not_found(page: Page, test_config):
"""With browser router, an unknown route should result in a 404 not found error
"""
page.goto(test_config["base_url"] + "/this-is-not-an-app-route")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, hm, yeah, that is confusing.

I have actually forgotten best practices for this.

I recently created a related conda-store server issue about creating a catch-all route that returns the UI app instead of a 404, if no other route is matched.

I will have to do some research, but I think that ultimately if we want an actual HTTP 404 status code, we will have to define the UI app routes in both the client-side and server-side code.

The only reason these nonsense routes, such as /foo-bar, return the UI app with a 200, by the way, is because of the --history-api-fallback Webpack dev server flag passed to the package.json start script:

"start:ui": "REACT_APP_VERSION=$npm_package_version webpack server --history-api-fallback",

Copy link
Contributor

@peytondmurray peytondmurray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In wondering about html error codes for invalid routes I realized I was getting hung up on a question about backend behavior, and it is I think somewhat tangential to these changes. If you're okay with it, let's merge! 🚢

@gabalafou gabalafou merged commit 0b26f86 into conda-incubator:main Oct 29, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: testing ✅ Design of the test infrastructure and everything related needs: review 👀 type: enhancement 💅🏼 New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants