github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/OverviewSidebarOptions.test.tsx (about) 1 import { render, screen } from "@testing-library/react" 2 import userEvent from "@testing-library/user-event" 3 import React, { ReactElement } from "react" 4 import { MemoryRouter } from "react-router" 5 import { AnalyticsAction, AnalyticsType } from "./analytics" 6 import { 7 cleanupMockAnalyticsCalls, 8 expectIncrs, 9 mockAnalyticsCalls, 10 } from "./analytics_test_helpers" 11 import { accessorsForTesting, tiltfileKeyContext } from "./BrowserStorage" 12 import Features, { FeaturesTestProvider, Flag } from "./feature" 13 import { 14 TenResourcesWithLabels, 15 TestsWithErrors, 16 TwoResourcesTwoTests, 17 } from "./OverviewResourceSidebar.stories" 18 import { OverviewSidebarOptionsRoot } from "./OverviewSidebarOptions" 19 import { ResourceGroupsContextProvider } from "./ResourceGroupsContext" 20 import { 21 DEFAULT_OPTIONS, 22 ResourceListOptions, 23 ResourceListOptionsProvider, 24 RESOURCE_LIST_OPTIONS_KEY, 25 } from "./ResourceListOptionsContext" 26 import { ResourceNameFilterTextField } from "./ResourceNameFilter" 27 import { SidebarItemNameRoot, SidebarItemRoot } from "./SidebarItemView" 28 import { 29 SidebarListSectionItemsRoot, 30 SidebarResourcesRoot, 31 } from "./SidebarResources" 32 33 const resourceListOptionsAccessor = accessorsForTesting<ResourceListOptions>( 34 RESOURCE_LIST_OPTIONS_KEY, 35 sessionStorage 36 ) 37 /** 38 * TODO (lizz): These tests behave more like integration tests 39 * and test the SidebarOptions component within the larger `SidebarResources` 40 * component. The tests should be moved over to that component's test suite 41 * and refactored with the react-testing-library changes. 42 */ 43 44 function assertSidebarItemsAndOptions( 45 root: HTMLElement, 46 names: string[], 47 expectAlertsOnTop: boolean, 48 expectedResourceNameFilter?: string 49 ) { 50 let sidebar = Array.from(root.querySelectorAll(SidebarResourcesRoot)) 51 expect(sidebar).toHaveLength(1) 52 53 // only check items in the "all resources" section, i.e. don't look at starred things 54 // or we'll have duplicates 55 let all = sidebar[0].querySelector(SidebarListSectionItemsRoot)! 56 let items = Array.from(all.querySelectorAll(SidebarItemRoot)) 57 const observedNames = items.map( 58 (i) => i.querySelector(SidebarItemNameRoot)?.textContent 59 ) 60 expect(observedNames).toEqual(names) 61 62 let optSetter = Array.from( 63 sidebar[0].querySelectorAll(OverviewSidebarOptionsRoot) 64 ) 65 expect(optSetter).toHaveLength(1) 66 67 let checkbox = optSetter[0].querySelector( 68 "input[type=checkbox]" 69 ) as HTMLInputElement 70 expect(checkbox.checked).toEqual(expectAlertsOnTop) 71 if (expectedResourceNameFilter !== undefined) { 72 expect( 73 optSetter[0].querySelector(ResourceNameFilterTextField)!.textContent 74 ).toEqual(expectedResourceNameFilter) 75 } 76 } 77 78 beforeEach(() => { 79 mockAnalyticsCalls() 80 }) 81 82 afterEach(() => { 83 cleanupMockAnalyticsCalls() 84 localStorage.clear() 85 resourceListOptionsAccessor.set({ 86 ...DEFAULT_OPTIONS, 87 }) 88 }) 89 90 function renderContainer(x: ReactElement) { 91 const features = new Features({ 92 [Flag.Labels]: true, 93 }) 94 const { container } = render( 95 <MemoryRouter> 96 <FeaturesTestProvider value={features}> 97 <tiltfileKeyContext.Provider value="test"> 98 <ResourceGroupsContextProvider> 99 <ResourceListOptionsProvider>{x}</ResourceListOptionsProvider> 100 </ResourceGroupsContextProvider> 101 </tiltfileKeyContext.Provider> 102 </FeaturesTestProvider> 103 </MemoryRouter> 104 ) 105 return container 106 } 107 108 describe("overview sidebar options", () => { 109 it("says no matches found", () => { 110 resourceListOptionsAccessor.set({ 111 ...DEFAULT_OPTIONS, 112 resourceNameFilter: "asdfawfwef", 113 }) 114 const container = renderContainer(<TwoResourcesTwoTests />) 115 const resourceSectionItems = Array.from( 116 container 117 .querySelector(SidebarListSectionItemsRoot)! 118 .querySelectorAll("li") 119 ) 120 expect(resourceSectionItems.map((n) => n.textContent)).toEqual([ 121 "No matching resources", 122 ]) 123 }) 124 }) 125 126 it("toggles/untoggles Alerts On Top sorting when button clicked", () => { 127 const { container } = render(TestsWithErrors()) 128 129 const origOrder = [ 130 "(Tiltfile)", 131 "test_0", 132 "test_1", 133 "test_2", 134 "test_3", 135 "test_4", 136 "test_5", 137 "test_6", 138 "test_7", 139 ] 140 const alertsOnTopOrder = [ 141 "test_0", 142 "test_2", 143 "test_4", 144 "test_6", 145 "(Tiltfile)", 146 "test_1", 147 "test_3", 148 "test_5", 149 "test_7", 150 ] 151 assertSidebarItemsAndOptions(container, origOrder, false) 152 153 let aotToggle = screen.getByLabelText("Alerts on top") 154 userEvent.click(aotToggle) 155 156 assertSidebarItemsAndOptions(container, alertsOnTopOrder, true) 157 158 userEvent.click(aotToggle) 159 assertSidebarItemsAndOptions(container, origOrder, false) 160 }) 161 162 describe("expand-all button", () => { 163 it("sends analytics onclick", () => { 164 const container = renderContainer(<TenResourcesWithLabels />) 165 userEvent.click(screen.getByTitle("Expand All")) 166 expectIncrs({ 167 name: "ui.web.expandAllGroups", 168 tags: { action: AnalyticsAction.Click, type: AnalyticsType.Detail }, 169 }) 170 }) 171 }) 172 173 describe("collapse-all button", () => { 174 it("sends analytics onclick", () => { 175 const container = renderContainer(<TenResourcesWithLabels />) 176 userEvent.click(screen.getByTitle("Collapse All")) 177 expectIncrs({ 178 name: "ui.web.collapseAllGroups", 179 tags: { action: AnalyticsAction.Click, type: AnalyticsType.Detail }, 180 }) 181 }) 182 })