forked from containers/podman-desktop
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add a way to debug stores in troubleshooting page
fixes containers#3053 Signed-off-by: Florent Benoit <fbenoit@redhat.com>
- Loading branch information
Showing
8 changed files
with
463 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
packages/renderer/src/lib/troubleshooting/TroubleshootingPageStore.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/********************************************************************** | ||
* Copyright (C) 2023 Red Hat, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
***********************************************************************/ | ||
|
||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
|
||
import '@testing-library/jest-dom'; | ||
import { beforeAll, test, expect, vi } from 'vitest'; | ||
import { fireEvent, render, screen } from '@testing-library/svelte'; | ||
import TroubleshootingPageStore from './TroubleshootingPageStore.svelte'; | ||
import type { EventStoreInfo } from '/@/stores/event-store'; | ||
|
||
beforeAll(() => {}); | ||
|
||
test('Check store info is displayed and clicking on buttons works', async () => { | ||
const clearEventsMock = vi.fn(); | ||
const fetchMock = vi.fn(); | ||
|
||
const eventStoreInfo: EventStoreInfo = { | ||
name: 'my-test-store', | ||
size: 3, | ||
bufferEvents: [], | ||
clearEvents: clearEventsMock, | ||
fetch: fetchMock, | ||
}; | ||
|
||
render(TroubleshootingPageStore, { eventStoreInfo }); | ||
|
||
// expect to have the Refresh button | ||
const refreshButton = screen.getByRole('button', { name: 'Refresh' }); | ||
expect(refreshButton).toBeInTheDocument(); | ||
|
||
// click on it | ||
await fireEvent.click(refreshButton); | ||
|
||
// expect to have fetch method called | ||
expect(fetchMock).toHaveBeenCalled(); | ||
|
||
// check we have open details button | ||
const openDetailsButton = screen.getByRole('button', { name: 'Open Details' }); | ||
expect(openDetailsButton).toBeInTheDocument(); | ||
|
||
// click on it | ||
await fireEvent.click(openDetailsButton); | ||
|
||
// expect to have dialog being displayed when clicking on the button | ||
const details = screen.getByRole('dialog', { name: 'Details of my-test-store' }); | ||
|
||
expect(details).toBeInTheDocument(); | ||
|
||
// expect to have the Cancel button | ||
const cancelButton = screen.getByRole('button', { name: 'Cancel' }); | ||
expect(cancelButton).toBeInTheDocument(); | ||
|
||
// click on it | ||
await fireEvent.click(cancelButton); | ||
|
||
// dialog should be hidden now | ||
expect(details).not.toBeInTheDocument(); | ||
}); |
57 changes: 57 additions & 0 deletions
57
packages/renderer/src/lib/troubleshooting/TroubleshootingPageStore.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<script lang="ts"> | ||
import TroubleshootingPageStoreDetails from './TroubleshootingPageStoreDetails.svelte'; | ||
import type { EventStoreInfo } from '/@/stores/event-store'; | ||
export let eventStoreInfo: EventStoreInfo; | ||
let fetchInProgress = false; | ||
async function fetch(): Promise<void> { | ||
fetchInProgress = true; | ||
try { | ||
await eventStoreInfo.fetch(); | ||
} finally { | ||
fetchInProgress = false; | ||
} | ||
} | ||
let openDetails = false; | ||
</script> | ||
|
||
<div class="flex flex-col bg-charcoal-600 p-2 items-center rounded w-full"> | ||
<div><svelte:component this="{eventStoreInfo.iconComponent}" size="20" /></div> | ||
<div class="text-xl"> | ||
<button | ||
disabled="{fetchInProgress}" | ||
class="underline outline-none" | ||
title="Open Details" | ||
aria-label="Open Details" | ||
on:click="{() => (openDetails = true)}"> | ||
{eventStoreInfo.name} | ||
</button> | ||
</div> | ||
<div class="text-sm">({eventStoreInfo.size} items)</div> | ||
<div class=""> | ||
<button | ||
disabled="{fetchInProgress}" | ||
class="px-3 my-1 text-sm font-medium text-center text-white bg-violet-600 rounded-sm hover:bg-dustypurple-800 focus:ring-2 focus:outline-none focus:ring-dustypurple-700 w-full" | ||
title="Refresh" | ||
aria-label="Refresh" | ||
on:click="{() => fetch()}"> | ||
Refresh | ||
</button> | ||
</div> | ||
{#if eventStoreInfo.bufferEvents.length > 0} | ||
{@const lastUpdate = eventStoreInfo.bufferEvents[eventStoreInfo.bufferEvents.length - 1]} | ||
{#if lastUpdate.humanDuration} | ||
<div class="text-xs italic" title="Time to update">{lastUpdate.humanDuration}</div> | ||
{/if} | ||
{/if} | ||
|
||
{#if openDetails} | ||
<TroubleshootingPageStoreDetails | ||
closeCallback="{() => { | ||
openDetails = false; | ||
}}" | ||
eventStoreInfo="{eventStoreInfo}" /> | ||
{/if} | ||
</div> |
140 changes: 140 additions & 0 deletions
140
packages/renderer/src/lib/troubleshooting/TroubleshootingPageStoreDetails.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/********************************************************************** | ||
* Copyright (C) 2023 Red Hat, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
***********************************************************************/ | ||
|
||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
|
||
import '@testing-library/jest-dom'; | ||
import { beforeAll, test, expect, vi } from 'vitest'; | ||
import { fireEvent, render, screen } from '@testing-library/svelte'; | ||
import TroubleshootingPageStoreDetails from './TroubleshootingPageStoreDetails.svelte'; | ||
import type { EventStoreInfo } from '/@/stores/event-store'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
beforeAll(() => {}); | ||
|
||
test('Check details are displayed and works', async () => { | ||
const clearEventsMock = vi.fn(); | ||
const fetchMock = vi.fn(); | ||
const closeCallback = vi.fn(); | ||
|
||
const bufferEvent = { | ||
name: 'my-test-event', | ||
args: [], | ||
length: 5, | ||
date: new Date().getTime(), | ||
skipped: false, | ||
}; | ||
|
||
const eventStoreInfo: EventStoreInfo = { | ||
name: 'my-test-store', | ||
size: 3, | ||
bufferEvents: [bufferEvent], | ||
clearEvents: clearEventsMock, | ||
fetch: fetchMock, | ||
}; | ||
|
||
render(TroubleshootingPageStoreDetails, { eventStoreInfo, closeCallback }); | ||
|
||
// find the label with name size | ||
const sizeStatus = screen.getByRole('status', { name: 'size' }); | ||
expect(sizeStatus).toBeInTheDocument(); | ||
// value should be 3 | ||
expect(sizeStatus).toHaveTextContent('3'); | ||
|
||
// and check we have buffer events | ||
const bufferEvents = screen.getByRole('list', { name: 'buffer-events' }); | ||
expect(bufferEvents).toBeInTheDocument(); | ||
|
||
// expect to have li item in the list | ||
const bufferEvent1 = screen.getByRole('listitem', { name: 'my-test-event' }); | ||
expect(bufferEvent1).toBeInTheDocument(); | ||
// now check the text content | ||
expect(bufferEvent1).toHaveTextContent(`Grab ${bufferEvent.length} items from '${bufferEvent.name}' event`); | ||
}); | ||
|
||
test('Check close button', async () => { | ||
const clearEventsMock = vi.fn(); | ||
const fetchMock = vi.fn(); | ||
const closeCallback = vi.fn(); | ||
|
||
const eventStoreInfo: EventStoreInfo = { | ||
name: 'my-test-store', | ||
size: 3, | ||
bufferEvents: [], | ||
clearEvents: clearEventsMock, | ||
fetch: fetchMock, | ||
}; | ||
|
||
render(TroubleshootingPageStoreDetails, { eventStoreInfo, closeCallback }); | ||
|
||
// expect to have the close button | ||
const closeButton = screen.getByRole('button', { name: 'Close' }); | ||
expect(closeButton).toBeInTheDocument(); | ||
|
||
// click on close button and expect close callback to be called | ||
expect(closeCallback).not.toBeCalled(); | ||
await fireEvent.click(closeButton); | ||
expect(closeCallback).toBeCalled(); | ||
}); | ||
|
||
test('Check Cancel button', async () => { | ||
const clearEventsMock = vi.fn(); | ||
const fetchMock = vi.fn(); | ||
const closeCallback = vi.fn(); | ||
|
||
const eventStoreInfo: EventStoreInfo = { | ||
name: 'my-test-store', | ||
size: 3, | ||
bufferEvents: [], | ||
clearEvents: clearEventsMock, | ||
fetch: fetchMock, | ||
}; | ||
|
||
render(TroubleshootingPageStoreDetails, { eventStoreInfo, closeCallback }); | ||
|
||
// expect to have the close button | ||
const cancelButton = screen.getByRole('button', { name: 'Cancel' }); | ||
expect(cancelButton).toBeInTheDocument(); | ||
|
||
// click on Cancel button and expect close callback to be called | ||
expect(closeCallback).not.toBeCalled(); | ||
await fireEvent.click(cancelButton); | ||
expect(closeCallback).toBeCalled(); | ||
}); | ||
|
||
test('Check ESC key', async () => { | ||
const clearEventsMock = vi.fn(); | ||
const fetchMock = vi.fn(); | ||
const closeCallback = vi.fn(); | ||
|
||
const eventStoreInfo: EventStoreInfo = { | ||
name: 'my-test-store', | ||
size: 3, | ||
bufferEvents: [], | ||
clearEvents: clearEventsMock, | ||
fetch: fetchMock, | ||
}; | ||
|
||
render(TroubleshootingPageStoreDetails, { eventStoreInfo, closeCallback }); | ||
|
||
// click on Cancel button and expect close callback to be called | ||
expect(closeCallback).not.toBeCalled(); | ||
// now, press the ESC key | ||
await userEvent.keyboard('{Escape}'); | ||
expect(closeCallback).toBeCalled(); | ||
}); |
Oops, something went wrong.