mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Adding TreeView & ScrollSpy tests
Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
parent
8339ecc5f1
commit
66994bdf4c
@ -306,7 +306,7 @@
|
||||
"concurrently": "^5.2.0",
|
||||
"css-element-queries": "^1.2.3",
|
||||
"css-loader": "^3.5.3",
|
||||
"deepdash-es": "^5.3.5",
|
||||
"deepdash": "^5.3.5",
|
||||
"dompurify": "^2.0.11",
|
||||
"electron": "^9.4.0",
|
||||
"electron-builder": "^22.7.0",
|
||||
|
||||
@ -80,9 +80,9 @@ export class PageLayout extends React.Component<PageLayoutProps> {
|
||||
<div className="content-scrollable-area">
|
||||
<div className="content-wrapper">
|
||||
{ showNavigation && (
|
||||
<div className="content-navigation">
|
||||
<nav className="content-navigation">
|
||||
<RecursiveTreeView data={navigation}/>
|
||||
</div>
|
||||
</nav>
|
||||
)}
|
||||
<div className={cssNames("content", contentGaps && "flex column gaps", contentClass)}>
|
||||
{children}
|
||||
|
||||
186
src/renderer/components/scroll-spy/__tests__/scroll-spy.test.tsx
Normal file
186
src/renderer/components/scroll-spy/__tests__/scroll-spy.test.tsx
Normal file
@ -0,0 +1,186 @@
|
||||
import React from "react";
|
||||
import "@testing-library/jest-dom/extend-expect";
|
||||
import { render, waitFor } from "@testing-library/react";
|
||||
import { ScrollSpy } from "../scroll-spy";
|
||||
import { RecursiveTreeView } from "../../tree-view";
|
||||
|
||||
const observe = jest.fn();
|
||||
|
||||
Object.defineProperty(window, "IntersectionObserver", {
|
||||
writable: true,
|
||||
value: jest.fn().mockImplementation(() => ({
|
||||
observe,
|
||||
unobserve: jest.fn(),
|
||||
})),
|
||||
});
|
||||
|
||||
describe("<ScrollSpy/>", () => {
|
||||
it("renders w/o errors", () => {
|
||||
const { container } = render(<ScrollSpy render={() => (
|
||||
<div>
|
||||
<section id="application">
|
||||
<h1>Application</h1>
|
||||
</section>
|
||||
</div>
|
||||
)}/>);
|
||||
|
||||
expect(container).toBeInstanceOf(HTMLElement);
|
||||
});
|
||||
|
||||
it("calls intersection observer", () => {
|
||||
render(<ScrollSpy render={() => (
|
||||
<div>
|
||||
<section id="application">
|
||||
<h1>Application</h1>
|
||||
</section>
|
||||
</div>
|
||||
)}/>);
|
||||
|
||||
expect(observe).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("renders navigation component", async () => {
|
||||
const { queryByTestId } = render(<ScrollSpy render={navigation => (
|
||||
<div>
|
||||
<nav>
|
||||
<RecursiveTreeView data={navigation}/>
|
||||
</nav>
|
||||
<section id="application">
|
||||
<h1>Application</h1>
|
||||
</section>
|
||||
</div>
|
||||
)}/>);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(queryByTestId("TreeView")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("throws if no sections founded", () => {
|
||||
// Prevent writing to stderr during this render.
|
||||
const err = console.error;
|
||||
|
||||
console.error = jest.fn();
|
||||
|
||||
expect(() => render(<ScrollSpy render={() => (
|
||||
<div>
|
||||
Content
|
||||
</div>
|
||||
)}/>)).toThrow();
|
||||
|
||||
// Restore writing to stderr.
|
||||
console.error = err;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("<TreeView/> navigation inside <ScrollSpy/>", () => {
|
||||
it("contains links to all sections", async () => {
|
||||
const { queryByTitle } = render(<ScrollSpy render={navigation => (
|
||||
<div>
|
||||
<nav>
|
||||
<RecursiveTreeView data={navigation}/>
|
||||
</nav>
|
||||
<section id="application">
|
||||
<h1>Application</h1>
|
||||
<section id="appearance">
|
||||
<h2>Appearance</h2>
|
||||
</section>
|
||||
<section id="theme">
|
||||
<h2>Theme</h2>
|
||||
<div>description</div>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
)}/>);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(queryByTitle("Application")).toBeInTheDocument();
|
||||
expect(queryByTitle("Appearance")).toBeInTheDocument();
|
||||
expect(queryByTitle("Theme")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("not showing links to sections without id", async () => {
|
||||
const { queryByTitle } = render(<ScrollSpy render={navigation => (
|
||||
<div>
|
||||
<nav>
|
||||
<RecursiveTreeView data={navigation}/>
|
||||
</nav>
|
||||
<section id="application">
|
||||
<h1>Application</h1>
|
||||
<section>
|
||||
<h2>Kubectl</h2>
|
||||
</section>
|
||||
<section id="appearance">
|
||||
<h2>Appearance</h2>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
)}/>);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(queryByTitle("Application")).toBeInTheDocument();
|
||||
expect(queryByTitle("Appearance")).toBeInTheDocument();
|
||||
expect(queryByTitle("Kubectl")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("expands parent sections", async () => {
|
||||
const { queryByTitle } = render(<ScrollSpy render={navigation => (
|
||||
<div>
|
||||
<nav>
|
||||
<RecursiveTreeView data={navigation}/>
|
||||
</nav>
|
||||
<section id="application">
|
||||
<h1>Application</h1>
|
||||
<section id="appearance">
|
||||
<h2>Appearance</h2>
|
||||
</section>
|
||||
<section id="theme">
|
||||
<h2>Theme</h2>
|
||||
<div>description</div>
|
||||
</section>
|
||||
</section>
|
||||
<section id="Kubernetes">
|
||||
<h1>Kubernetes</h1>
|
||||
<section id="kubectl">
|
||||
<h2>Kubectl</h2>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
)}/>);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(queryByTitle("Application")).toHaveAttribute("aria-expanded");
|
||||
expect(queryByTitle("Kubernetes")).toHaveAttribute("aria-expanded");
|
||||
});
|
||||
|
||||
// console.log(prettyDOM());
|
||||
});
|
||||
|
||||
it("skips sections without headings", async () => {
|
||||
const { queryByTitle } = render(<ScrollSpy render={navigation => (
|
||||
<div>
|
||||
<nav>
|
||||
<RecursiveTreeView data={navigation}/>
|
||||
</nav>
|
||||
<section id="application">
|
||||
<h1>Application</h1>
|
||||
<section id="appearance">
|
||||
<p>Appearance</p>
|
||||
</section>
|
||||
<section id="theme">
|
||||
<h2>Theme</h2>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
)}/>);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(queryByTitle("Application")).toBeInTheDocument();
|
||||
expect(queryByTitle("appearance")).not.toBeInTheDocument();
|
||||
expect(queryByTitle("Appearance")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -31,7 +31,7 @@ export function ScrollSpy(props: Props) {
|
||||
sections.forEach(section => {
|
||||
const id = section.getAttribute("id");
|
||||
const parentId = section.parentElement.id;
|
||||
const name = section.querySelector("h1, h2, h3, h4, h5, h6").textContent;
|
||||
const name = section.querySelector("h1, h2, h3, h4, h5, h6")?.textContent;
|
||||
const selected = id === activeElementId;
|
||||
|
||||
if (!name || !id) {
|
||||
|
||||
@ -5,7 +5,11 @@ import { Icon } from "../icon";
|
||||
import TreeView from "@material-ui/lab/TreeView";
|
||||
import TreeItem from "@material-ui/lab/TreeItem";
|
||||
import { cssNames } from "../../utils";
|
||||
import findDeep from "deepdash-es/findDeep";
|
||||
|
||||
import _ from "lodash";
|
||||
import getDeepDash from "deepdash";
|
||||
|
||||
const deepDash = getDeepDash(_);
|
||||
|
||||
export interface NavigationTree {
|
||||
id: string;
|
||||
@ -26,7 +30,7 @@ const scrollToItem = (id: string) => {
|
||||
};
|
||||
|
||||
const getSelectedNode = (data: NavigationTree[]) => {
|
||||
return findDeep(data, (value, key) => key === "selected" && value === true)?.parent;
|
||||
return deepDash.findDeep(data, (value, key) => key === "selected" && value === true)?.parent;
|
||||
};
|
||||
|
||||
export function RecursiveTreeView({ data }: Props) {
|
||||
@ -63,6 +67,7 @@ export function RecursiveTreeView({ data }: Props) {
|
||||
label={node.name}
|
||||
onLabelClick={(event) => onLabelClick(event, node.id)}
|
||||
className={cssNames({selected: node.selected})}
|
||||
title={node.name}
|
||||
>
|
||||
{Array.isArray(node.children) ? node.children.map((node) => renderTree([node])) : null}
|
||||
</TreeItem>
|
||||
@ -84,6 +89,7 @@ export function RecursiveTreeView({ data }: Props) {
|
||||
|
||||
return (
|
||||
<TreeView
|
||||
data-testid="TreeView"
|
||||
className="TreeView"
|
||||
expanded={expanded}
|
||||
onNodeToggle={handleToggle}
|
||||
|
||||
16
yarn.lock
16
yarn.lock
@ -4381,12 +4381,13 @@ deep-is@^0.1.3, deep-is@~0.1.3:
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
|
||||
|
||||
deepdash-es@^5.3.5:
|
||||
deepdash@^5.3.5:
|
||||
version "5.3.5"
|
||||
resolved "https://registry.yarnpkg.com/deepdash-es/-/deepdash-es-5.3.5.tgz#1217365f6508bb47f1f90def6b4f1c4b5f4ff6eb"
|
||||
integrity sha512-bezxT+LqAu1Ly8I2LAEFle3fdEAc/bHld9cMAbgYzY+69+P9qTkGtNvC2ZQJEP4C1C2Fx9gVn/TCoQlAivWPDA==
|
||||
resolved "https://registry.yarnpkg.com/deepdash/-/deepdash-5.3.5.tgz#611bec9c1f2829832d21971dcbefe712e408647d"
|
||||
integrity sha512-1ZdPPCI1pCEqeAWGSw+Nbpb/2iIV4w3sGPc22H/PDtcApb8+psTzPIoOVD040iBaT2wqZab29Kjrz6G+cd5mqQ==
|
||||
dependencies:
|
||||
lodash-es "^4.17.15"
|
||||
lodash "^4.17.20"
|
||||
lodash-es "^4.17.20"
|
||||
|
||||
deepmerge@^4.2.2:
|
||||
version "4.2.2"
|
||||
@ -8644,7 +8645,7 @@ lockfile@^1.0.4:
|
||||
dependencies:
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
lodash-es@^4.17.15:
|
||||
lodash-es@^4.17.20:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
|
||||
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
|
||||
@ -8707,6 +8708,11 @@ lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.1
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|
||||
|
||||
lodash@^4.17.20:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
logform@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/logform/-/logform-2.1.2.tgz#957155ebeb67a13164069825ce67ddb5bb2dd360"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user