1818
1919import '@testing-library/jest-dom/vitest' ;
2020
21- import { render , screen } from '@testing-library/svelte' ;
21+ import { render , type RenderResult } from '@testing-library/svelte' ;
2222import userEvent from '@testing-library/user-event' ;
23- import { tick } from 'svelte' ;
23+ import { type Component , type ComponentProps } from 'svelte' ;
2424import { beforeAll , beforeEach , expect , test , vi } from 'vitest' ;
2525
26- import type { GitHubIssue } from '/@api/feedback' ;
26+ import type { FeedbackCategory } from '/@api/feedback' ;
2727
2828import GitHubIssueFeedback from './GitHubIssueFeedback.svelte' ;
2929
@@ -49,98 +49,138 @@ beforeEach(() => {
4949 vi . resetAllMocks ( ) ;
5050} ) ;
5151
52+ /**
53+ * Utility method to query get GitHub issue inputs
54+ * @param props
55+ */
56+ function renderGitHubIssueFeedback ( props : ComponentProps < typeof GitHubIssueFeedback > ) : {
57+ title : HTMLInputElement ;
58+ description : HTMLTextAreaElement ;
59+ preview : HTMLButtonElement ;
60+ } & RenderResult < Component < ComponentProps < typeof GitHubIssueFeedback > > > {
61+ const { getByRole, queryByTitle, ...restResult } = render ( GitHubIssueFeedback , props ) ;
62+
63+ // text inputs
64+ const title = getByRole ( 'textbox' , { name : 'Issue Title' } ) ;
65+ expect ( title ) . toBeInstanceOf ( HTMLInputElement ) ;
66+
67+ const description = getByRole ( 'textbox' , { name : 'Issue Description' } ) ;
68+ expect ( description ) . toBeInstanceOf ( HTMLTextAreaElement ) ;
69+
70+ // button
71+ const preview = getByRole ( 'button' , { name : 'Preview on GitHub' } ) ;
72+ expect ( preview ) . toBeInstanceOf ( HTMLButtonElement ) ;
73+
74+ return {
75+ title : title as HTMLInputElement ,
76+ description : description as HTMLTextAreaElement ,
77+ preview : preview as HTMLButtonElement ,
78+ getByRole,
79+ queryByTitle,
80+ ...restResult ,
81+ } ;
82+ }
83+
5284test ( 'Expect feedback form to to be GitHub issue feedback form' , async ( ) => {
53- const renderObject = render ( GitHubIssueFeedback , { category : 'bug' , onCloseForm : vi . fn ( ) , contentChange : vi . fn ( ) } ) ;
85+ const { title, description } = renderGitHubIssueFeedback ( {
86+ category : 'bug' ,
87+ onCloseForm : vi . fn ( ) ,
88+ contentChange : vi . fn ( ) ,
89+ } ) ;
5490
55- expect ( screen . getByText ( 'Title' ) ) . toBeInTheDocument ( ) ;
56- expect ( screen . getByText ( 'Description' ) ) . toBeInTheDocument ( ) ;
57- renderObject . unmount ( ) ;
91+ expect ( title ) . toBeInTheDocument ( ) ;
92+ expect ( description ) . toBeInTheDocument ( ) ;
5893} ) ;
5994
6095test ( 'Expect Preview on GitHub button to be disabled if there is no title or description' , async ( ) => {
61- const renderObject = render ( GitHubIssueFeedback , { category : 'bug' , onCloseForm : vi . fn ( ) , contentChange : vi . fn ( ) } ) ;
62-
63- expect ( screen . getByRole ( 'button' , { name : 'Preview on GitHub' } ) ) . toBeDisabled ( ) ;
96+ const { title, description, preview } = renderGitHubIssueFeedback ( {
97+ category : 'bug' ,
98+ onCloseForm : vi . fn ( ) ,
99+ contentChange : vi . fn ( ) ,
100+ } ) ;
64101
65- const issueTitle = screen . getByTestId ( 'issueTitle' ) ;
66- expect ( issueTitle ) . toBeInTheDocument ( ) ;
67- await userEvent . type ( issueTitle , 'Bug title' ) ;
102+ // default: disabled
103+ expect ( preview ) . toBeDisabled ( ) ;
68104
69- const issueDescription = screen . getByTestId ( 'issueDescription' ) ;
70- expect ( issueDescription ) . toBeInTheDocument ( ) ;
71- await userEvent . type ( issueDescription , 'Bug description' ) ;
105+ await userEvent . type ( title , 'Bug title' ) ;
106+ await userEvent . type ( description , 'Bug description' ) ;
72107
73- await tick ( ) ;
74- expect ( screen . getByRole ( 'button' , { name : 'Preview on GitHub' } ) ) . toBeEnabled ( ) ;
75- renderObject . unmount ( ) ;
108+ await vi . waitFor ( ( ) => {
109+ expect ( preview ) . toBeEnabled ( ) ;
110+ } ) ;
76111} ) ;
77112
78- test ( 'Expect to have different placeholders for bug vs feaure' , async ( ) => {
79- let renderObject = render ( GitHubIssueFeedback , { category : 'bug' , onCloseForm : vi . fn ( ) , contentChange : vi . fn ( ) } ) ;
80-
81- let issueTitle = screen . getByTestId ( 'issueTitle' ) ;
82- expect ( issueTitle ) . toBeInTheDocument ( ) ;
83- expect ( issueTitle ) . toHaveProperty ( 'placeholder' , 'Bug Report Title' ) ;
84-
85- let issueDescription = screen . getByTestId ( 'issueDescription' ) ;
86- expect ( issueDescription ) . toBeInTheDocument ( ) ;
87- expect ( issueDescription ) . toHaveProperty ( 'placeholder' , 'Bug description' ) ;
88-
89- renderObject . unmount ( ) ;
90-
91- renderObject = render ( GitHubIssueFeedback , { category : 'feature' , onCloseForm : vi . fn ( ) , contentChange : vi . fn ( ) } ) ;
92-
93- issueTitle = screen . getByTestId ( 'issueTitle' ) ;
94- expect ( issueTitle ) . toBeInTheDocument ( ) ;
95- expect ( issueTitle ) . toHaveProperty ( 'placeholder' , 'Feature name' ) ;
113+ test . each ( [
114+ {
115+ category : 'bug' ,
116+ placeholders : {
117+ title : 'Bug Report Title' ,
118+ description : 'Bug description' ,
119+ } ,
120+ } ,
121+ {
122+ category : 'feature' ,
123+ placeholders : {
124+ title : 'Feature name' ,
125+ description : 'Feature description' ,
126+ } ,
127+ } ,
128+ ] ) ( '$category should have specific placeholders' , async ( { category, placeholders } ) => {
129+ const { title, description } = renderGitHubIssueFeedback ( {
130+ category : category as FeedbackCategory ,
131+ onCloseForm : vi . fn ( ) ,
132+ contentChange : vi . fn ( ) ,
133+ } ) ;
96134
97- issueDescription = screen . getByTestId ( 'issueDescription' ) ;
98- expect ( issueDescription ) . toBeInTheDocument ( ) ;
99- expect ( issueDescription ) . toHaveProperty ( 'placeholder' , 'Feature description' ) ;
100- renderObject . unmount ( ) ;
135+ expect ( title ) . toHaveProperty ( 'placeholder' , placeholders . title ) ;
136+ expect ( description ) . toHaveProperty ( 'placeholder' , placeholders . description ) ;
101137} ) ;
102138
103- test ( 'Expect to have different existing GitHub issues links for bug and feature categories' , async ( ) => {
104- let renderObject = render ( GitHubIssueFeedback , { category : 'bug' , onCloseForm : vi . fn ( ) , contentChange : vi . fn ( ) } ) ;
105- let existingIssues = screen . getByLabelText ( 'GitHub issues' ) ;
106- expect ( existingIssues ) . toBeInTheDocument ( ) ;
107-
108- await userEvent . click ( existingIssues ) ;
109- expect ( openExternalMock ) . toHaveBeenCalledWith (
110- 'https://github.com/podman-desktop/podman-desktop/issues?q=label%3A%22kind%2Fbug%20%F0%9F%90%9E%22' ,
111- ) ;
112- renderObject . unmount ( ) ;
139+ test . each ( [
140+ {
141+ category : 'bug' ,
142+ link : 'https://github.com/podman-desktop/podman-desktop/issues?q=label%3A%22kind%2Fbug%20%F0%9F%90%9E%22' ,
143+ } ,
144+ {
145+ category : 'feature' ,
146+ link : 'https://github.com/podman-desktop/podman-desktop/issues?q=label%3A%22kind%2Ffeature%20%F0%9F%92%A1%22' ,
147+ } ,
148+ ] ) ( '$category should have specific issues link' , async ( { category, link } ) => {
149+ const { getByLabelText } = renderGitHubIssueFeedback ( {
150+ category : category as FeedbackCategory ,
151+ onCloseForm : vi . fn ( ) ,
152+ contentChange : vi . fn ( ) ,
153+ } ) ;
113154
114- renderObject = render ( GitHubIssueFeedback , { category : 'feature' , onCloseForm : vi . fn ( ) , contentChange : vi . fn ( ) } ) ;
115- existingIssues = screen . getByLabelText ( 'GitHub issues' ) ;
155+ const existingIssues = getByLabelText ( 'GitHub issues' ) ;
116156 expect ( existingIssues ) . toBeInTheDocument ( ) ;
117157
118158 await userEvent . click ( existingIssues ) ;
119- expect ( openExternalMock ) . toHaveBeenCalledWith (
120- 'https://github.com/podman-desktop/podman-desktop/issues?q=label%3A%22kind%2Ffeature%20%F0%9F%92%A1%22' ,
121- ) ;
122- renderObject . unmount ( ) ;
159+ expect ( openExternalMock ) . toHaveBeenCalledWith ( link ) ;
123160} ) ;
124161
125- test ( 'Expect the right category to be included in previewOnGitHub call' , async ( ) => {
126- const issueProperties : GitHubIssue = {
127- category : 'bug' ,
128- title : 'Bug title' ,
129- description : 'Bug description' ,
130- } ;
131- const renderObject = render ( GitHubIssueFeedback , { category : 'bug' , onCloseForm : vi . fn ( ) , contentChange : vi . fn ( ) } ) ;
132- const previewButton = screen . getByRole ( 'button' , { name : 'Preview on GitHub' } ) ;
162+ test . each ( [ 'bug' , 'feature' ] ) ( 'Expect %s to be included in previewOnGitHub call' , async category => {
163+ const { preview, title, description } = renderGitHubIssueFeedback ( {
164+ category : category as FeedbackCategory ,
165+ onCloseForm : vi . fn ( ) ,
166+ contentChange : vi . fn ( ) ,
167+ } ) ;
133168
134- const issueTitle = screen . getByTestId ( 'issueTitle' ) ;
135- expect ( issueTitle ) . toBeInTheDocument ( ) ;
136- await userEvent . type ( issueTitle , 'Bug title ' ) ;
169+ // type dummy data
170+ await userEvent . type ( title , 'Bug title' ) ;
171+ await userEvent . type ( description , 'Bug description ' ) ;
137172
138- const issueDescription = screen . getByTestId ( 'issueDescription' ) ;
139- expect ( issueDescription ) . toBeInTheDocument ( ) ;
140- await userEvent . type ( issueDescription , 'Bug description' ) ;
173+ // wait enable
174+ await vi . waitFor ( ( ) => {
175+ expect ( preview ) . toBeEnabled ( ) ;
176+ } ) ;
141177
142- await userEvent . click ( previewButton ) ;
178+ // preview
179+ await userEvent . click ( preview ) ;
143180
144- expect ( previewOnGitHubMock ) . toHaveBeenCalledWith ( issueProperties ) ;
145- renderObject . unmount ( ) ;
181+ expect ( previewOnGitHubMock ) . toHaveBeenCalledWith (
182+ expect . objectContaining ( {
183+ category : category ,
184+ } ) ,
185+ ) ;
146186} ) ;
0 commit comments