fix(web): name plugin item actions (#40261)

This commit is contained in:
yyh
2026-08-10 11:13:33 +08:00
committed by GitHub
parent e8afed13cc
commit e12563a4b4
2 changed files with 52 additions and 42 deletions
@@ -133,11 +133,13 @@ const createActionProps = (overrides: Partial<ActionProps> = {}): ActionProps =>
const getDeleteConfirmButton = () =>
screen.getByRole('button', { name: /common\.operation\.confirm/ })
const getDeleteCancelButton = () => screen.getByRole('button', { name: 'common.operation.cancel' })
const getCheckForUpdatesButton = () =>
screen.getByRole('button', { name: 'plugin.action.checkForUpdates' })
const getPluginInfoButton = () => screen.getByRole('button', { name: 'plugin.action.pluginInfo' })
const getDeleteButton = () => screen.getByRole('button', { name: 'plugin.action.delete' })
// ==================== Tests ====================
// Helper to find action buttons (real ActionButton component uses type="button")
const getActionButtons = () => screen.getAllByRole('button')
const queryActionButtons = () => screen.queryAllByRole('button')
describe('Action Component', () => {
@@ -165,7 +167,7 @@ describe('Action Component', () => {
render(<Action {...props} />)
// Assert
expect(getActionButtons()).toHaveLength(1)
expect(getDeleteButton()).toBeInTheDocument()
})
it('should render fetch new version button when isShowFetchNewVersion is true', () => {
@@ -180,7 +182,7 @@ describe('Action Component', () => {
render(<Action {...props} />)
// Assert
expect(getActionButtons()).toHaveLength(1)
expect(getCheckForUpdatesButton()).toBeInTheDocument()
})
it('should render info button when isShowInfo is true', () => {
@@ -195,7 +197,7 @@ describe('Action Component', () => {
render(<Action {...props} />)
// Assert
expect(getActionButtons()).toHaveLength(1)
expect(getPluginInfoButton()).toBeInTheDocument()
})
it('should render all buttons when all flags are true', () => {
@@ -210,7 +212,9 @@ describe('Action Component', () => {
render(<Action {...props} />)
// Assert
expect(getActionButtons()).toHaveLength(3)
expect(getCheckForUpdatesButton()).toBeInTheDocument()
expect(getPluginInfoButton()).toBeInTheDocument()
expect(getDeleteButton()).toBeInTheDocument()
})
it('should render no buttons when all flags are false', () => {
@@ -241,16 +245,15 @@ describe('Action Component', () => {
render(<Action {...props} />)
// Assert
const buttons = getActionButtons()
await user.hover(buttons[0]!)
await user.hover(getCheckForUpdatesButton())
expect(await screen.findByText('plugin.action.checkForUpdates'))!.toBeInTheDocument()
await user.unhover(buttons[0]!)
await user.unhover(getCheckForUpdatesButton())
await user.hover(buttons[1]!)
await user.hover(getPluginInfoButton())
expect(await screen.findByText('plugin.action.pluginInfo'))!.toBeInTheDocument()
await user.unhover(buttons[1]!)
await user.unhover(getPluginInfoButton())
await user.hover(buttons[2]!)
await user.hover(getDeleteButton())
expect(await screen.findByText('plugin.action.delete'))!.toBeInTheDocument()
})
})
@@ -267,7 +270,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
// Assert
expect(screen.getByRole('heading', { name: 'plugin.action.delete' }))!.toBeInTheDocument()
@@ -284,7 +287,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
// Assert
// Assert
@@ -301,7 +304,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
expect(screen.getByRole('heading', { name: 'plugin.action.delete' }))!.toBeInTheDocument()
fireEvent.click(getDeleteCancelButton())
@@ -323,7 +326,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
// Assert
@@ -345,7 +348,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
// Assert
@@ -365,7 +368,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
// Assert
@@ -387,7 +390,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
// Assert
@@ -409,7 +412,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
// Assert
@@ -436,7 +439,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
// Assert - Loading state
@@ -469,7 +472,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getPluginInfoButton())
// Assert
// Assert
@@ -495,7 +498,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getPluginInfoButton())
expect(screen.getByTestId('plugin-info-modal'))!.toBeInTheDocument()
fireEvent.click(screen.getByTestId('close-plugin-info'))
@@ -554,7 +557,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getCheckForUpdatesButton())
// Assert
await waitFor(() => {
@@ -580,7 +583,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getCheckForUpdatesButton())
// Assert
await waitFor(() => {
@@ -599,7 +602,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getCheckForUpdatesButton())
// Assert
await waitFor(() => {
@@ -623,7 +626,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getCheckForUpdatesButton())
// Assert - toast is called with the translated payload
await waitFor(() => {
@@ -657,7 +660,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getCheckForUpdatesButton())
// Assert
await waitFor(() => {
@@ -697,7 +700,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getCheckForUpdatesButton())
// Wait for modal to be called
await waitFor(() => {
@@ -729,7 +732,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getCheckForUpdatesButton())
// Assert
await waitFor(() => {
@@ -758,7 +761,7 @@ describe('Action Component', () => {
// Act
const { rerender } = render(<Action {...props1} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
await waitFor(() => {
@@ -767,7 +770,7 @@ describe('Action Component', () => {
mockUninstallPlugin.mockClear()
rerender(<Action {...props2} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
await waitFor(() => {
@@ -795,7 +798,7 @@ describe('Action Component', () => {
// Act
const { rerender } = render(<Action {...props1} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
await waitFor(() => {
@@ -804,7 +807,7 @@ describe('Action Component', () => {
expect(onDelete2).not.toHaveBeenCalled()
rerender(<Action {...props2} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
await waitFor(() => {
@@ -833,7 +836,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getCheckForUpdatesButton())
// Assert - Should use author and pluginName as fallback
await waitFor(() => {
@@ -857,7 +860,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
fireEvent.click(getDeleteConfirmButton())
// The confirm button should be disabled during deletion
@@ -883,7 +886,7 @@ describe('Action Component', () => {
// Act
render(<Action {...props} />)
fireEvent.click(getActionButtons()[0]!)
fireEvent.click(getDeleteButton())
// Assert
// Assert
@@ -120,8 +120,11 @@ const Action: FC<Props> = ({
<Tooltip>
<TooltipTrigger
render={
<ActionButton onClick={handleFetchNewVersion}>
<span className="i-ri-loop-left-line size-4 text-text-tertiary" />
<ActionButton
aria-label={t(($) => $[`${i18nPrefix}.checkForUpdates`], { ns: 'plugin' })}
onClick={handleFetchNewVersion}
>
<span aria-hidden className="i-ri-loop-left-line size-4 text-text-tertiary" />
</ActionButton>
}
/>
@@ -134,8 +137,11 @@ const Action: FC<Props> = ({
<Tooltip>
<TooltipTrigger
render={
<ActionButton onClick={showPluginInfo}>
<span className="i-ri-information-2-line size-4 text-text-tertiary" />
<ActionButton
aria-label={t(($) => $[`${i18nPrefix}.pluginInfo`], { ns: 'plugin' })}
onClick={showPluginInfo}
>
<span aria-hidden className="i-ri-information-2-line size-4 text-text-tertiary" />
</ActionButton>
}
/>
@@ -149,10 +155,11 @@ const Action: FC<Props> = ({
<TooltipTrigger
render={
<ActionButton
aria-label={t(($) => $[`${i18nPrefix}.delete`], { ns: 'plugin' })}
className="text-text-tertiary hover:bg-state-destructive-hover hover:text-text-destructive"
onClick={showDeleteConfirm}
>
<span className="i-ri-delete-bin-line size-4" />
<span aria-hidden className="i-ri-delete-bin-line size-4" />
</ActionButton>
}
/>