Skip to content

Commit

Permalink
Add React router tests (#430)
Browse files Browse the repository at this point in the history
  • Loading branch information
gabalafou authored Oct 29, 2024
1 parent 370e327 commit 0b26f86
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/layouts/PageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const PageLayout = () => {
justifyContent: "center",
height: "100%"
}}
data-testid="no-environment-selected"
>
<Typography sx={{ fontSize: "18px", color: "#333" }}>
Select an environment to show details
Expand Down
35 changes: 18 additions & 17 deletions src/preferences.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,55 +21,56 @@ export interface IPreferences {
urlBasename: string;
}

const { condaStoreConfig = {} } =
typeof window !== "undefined" && (window as any);
let condaStoreConfig: any = {};
if (typeof window !== "undefined" && "condaStoreConfig" in window) {
condaStoreConfig = window.condaStoreConfig;
}

export const prefDefault: Readonly<IPreferences> = {
apiUrl:
process.env.REACT_APP_API_URL ??
condaStoreConfig.REACT_APP_API_URL ??
process.env.REACT_APP_API_URL ??
"http://localhost:8080/conda-store/",

authMethod:
(process.env.REACT_APP_AUTH_METHOD as IPreferences["authMethod"]) ??
(condaStoreConfig.REACT_APP_AUTH_METHOD as IPreferences["authMethod"]) ??
condaStoreConfig.REACT_APP_AUTH_METHOD ??
process.env.REACT_APP_AUTH_METHOD ??
"cookie",

authToken:
process.env.REACT_APP_AUTH_TOKEN ??
condaStoreConfig.REACT_APP_AUTH_TOKEN ??
process.env.REACT_APP_AUTH_TOKEN ??
"",

loginUrl:
process.env.REACT_APP_LOGIN_PAGE_URL ??
condaStoreConfig.REACT_APP_LOGIN_PAGE_URL ??
process.env.REACT_APP_LOGIN_PAGE_URL ??
"http://localhost:8080/conda-store/login?next=",

styleType:
process.env.REACT_APP_STYLE_TYPE ??
condaStoreConfig.REACT_APP_STYLE_TYPE ??
process.env.REACT_APP_STYLE_TYPE ??
"green-accent",

showAuthButton: process.env.REACT_APP_SHOW_AUTH_BUTTON
? JSON.parse(process.env.REACT_APP_SHOW_AUTH_BUTTON)
: condaStoreConfig !== undefined &&
condaStoreConfig.REACT_APP_SHOW_AUTH_BUTTON !== undefined
? JSON.parse(condaStoreConfig.REACT_APP_SHOW_AUTH_BUTTON)
: true,
showAuthButton: /true/i.test(
condaStoreConfig.REACT_APP_SHOW_AUTH_BUTTON ??
process.env.REACT_APP_SHOW_AUTH_BUTTON ??
"true"
),

logoutUrl:
process.env.REACT_APP_LOGOUT_PAGE_URL ??
condaStoreConfig.REACT_APP_LOGOUT_PAGE_URL ??
process.env.REACT_APP_LOGOUT_PAGE_URL ??
"http://localhost:8080/conda-store/logout?next=/",

routerType:
process.env.REACT_APP_ROUTER_TYPE ??
condaStoreConfig.REACT_APP_ROUTER_TYPE ??
process.env.REACT_APP_ROUTER_TYPE ??
"browser",

urlBasename:
process.env.REACT_APP_URL_BASENAME ??
condaStoreConfig.REACT_APP_URL_BASENAME ??
process.env.REACT_APP_URL_BASENAME ??
"/"
};

Expand Down
12 changes: 12 additions & 0 deletions test/playwright/memory-router-test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html>
<head>
<script>
window.condaStoreConfig = {
REACT_APP_ROUTER_TYPE: "memory"
};
</script>
</head>
<body>
</body>
</html>
88 changes: 88 additions & 0 deletions test/playwright/test_react_router.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""Test app with different types of React routers
- browser router (uses the history API)
- memory router (uses in-app memory)
Ref: https://reactrouter.com/en/main/routers/create-memory-router
"""

import pytest
import re
from playwright.sync_api import Page, expect


@pytest.fixture
def test_config():
return {"base_url": "http://localhost:8000"}


def test_browser_router_200_ok(page: Page, test_config):
"""With browser router, a known route should show the corresponding view
"""
# Check that when going to a known route (in this case, the route to create
# a new environment), the app loads the view for that route.
page.goto(test_config["base_url"] + "/default/new-environment")

# We know we are at the correct view (i.e., new environment form) if there
# is a textbox to enter the name of the new environment.
expect(page.get_by_role("textbox", name="environment name")).to_be_visible()


def test_memory_router_200_ok():
"""With memory router, all routes are 200 (OK) so there's nothing to test there
"""
pass


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")
expect(page.get_by_text("404")).to_be_visible()


def test_memory_router_404_not_found(page: Page, test_config):
"""The memory router has been configured to load the root view at any route
"""
# The route `/memory-router-test.html` is not a route recognized by the
# React app. With the browser router, an unknown route would give a 404.
page.goto(test_config["base_url"] + "/memory-router-test.html")
expect(page.get_by_test_id("no-environment-selected")).to_be_visible()


def test_browser_router_updates_location(page: Page, test_config):
"""With browser router, following a link should update browser URL
"""
# Go to root view and verify that it loaded
page.goto(test_config["base_url"])
expect(page.get_by_test_id("no-environment-selected")).to_be_visible()

# Get and click link to "create new environment"
page.get_by_role("button", name="default").get_by_role(
"link",
# Note the accessible name is determined by the aria-label,
# not the link text
name=re.compile("new.*environment", re.IGNORECASE),
).click()

# With browser router, the window location should update in response to
# clicking an app link
expect(page).to_have_url(re.compile("/default/new-environment"))


def test_memory_router_does_not_update_location(page: Page, test_config):
"""With memory router, following a link should NOT update browser URL
"""
page.goto(test_config["base_url"] + "/memory-router-test.html")

# Get and click link to "create new environment"
page.get_by_role("button", name="default").get_by_role(
"link",
# Note the accessible name is determined by the aria-label,
# not the link text
name=re.compile("new.*environment", re.IGNORECASE),
).click()

# With memory router, the window location should **not** update in response
# to clicking an app link
expect(page).to_have_url(re.compile("/memory-router-test.html"))
10 changes: 7 additions & 3 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2020, conda-store development team
*
* This file is distributed under the terms of the BSD 3 Clause license.
* This file is distributed under the terms of the BSD 3 Clause license.
* The full license can be found in the LICENSE file.
*/

Expand All @@ -18,7 +18,7 @@ const isProd = process.env.NODE_ENV === "production";
const ASSET_PATH = isProd ? "" : "/";
const version = packageJson.version;

// Calculate hash based on content, will be used when generating production
// Calculate hash based on content, will be used when generating production
// bundles
const cssLoader = {
loader: "css-loader",
Expand Down Expand Up @@ -92,6 +92,10 @@ module.exports = {
},
plugins: [
new HtmlWebpackPlugin({ title: "conda-store" }),
new HtmlWebpackPlugin({
filename: "memory-router-test.html",
template: "test/playwright/memory-router-test.html",
}),
new MiniCssExtractPlugin({
filename: "[name].css",
}),
Expand All @@ -101,7 +105,7 @@ module.exports = {
new webpack.DefinePlugin({
'process.env.VERSION': JSON.stringify(version),
}),
// Add comment to generated files indicating the hash and ui version
// Add comment to generated files indicating the hash and ui version
// this is helpful for vendoring with server
new webpack.BannerPlugin({
banner: `file: [file], fullhash:[fullhash] - ui version: ${version}`,
Expand Down

0 comments on commit 0b26f86

Please sign in to comment.