@@ -155,3 +155,70 @@ test('user can create folders', async ({ page }) => {
155
155
await expect ( terminalOutput ) . toContainText ( folder , { useInnerText : true } ) ;
156
156
}
157
157
} ) ;
158
+
159
+ test ( 'user can create files and folders in allowed directories' , async ( { page } ) => {
160
+ await page . goto ( `${ BASE_URL } /allow-edits-glob` ) ;
161
+ await expect ( page . getByRole ( 'heading' , { level : 1 , name : 'File Tree test - Allow Edits Glob' } ) ) . toBeVisible ( ) ;
162
+
163
+ // wait for terminal to start
164
+ const terminal = page . getByRole ( 'textbox' , { name : 'Terminal input' } ) ;
165
+ const terminalOutput = page . getByRole ( 'tabpanel' , { name : 'Terminal' } ) ;
166
+ await expect ( terminalOutput ) . toContainText ( '~/tutorial' , { useInnerText : true } ) ;
167
+
168
+ // can create files in root and inside "second-level"
169
+ for ( const [ locator , name , type ] of [
170
+ [ page . getByTestId ( 'file-tree-root-context-menu' ) , 'new-file.js' , 'file' ] ,
171
+ [ page . getByRole ( 'button' , { name : 'second-level' } ) , 'new-folder.js' , 'folder' ] ,
172
+ ] as const ) {
173
+ await locator . click ( { button : 'right' } ) ;
174
+ await page . getByRole ( 'menuitem' , { name : `Create ${ type } ` } ) . click ( ) ;
175
+
176
+ await page . locator ( '*:focus' ) . fill ( name ) ;
177
+ await page . locator ( '*:focus' ) . press ( 'Enter' ) ;
178
+ await expect ( page . getByRole ( 'button' , { name } ) ) . toBeVisible ( ) ;
179
+ }
180
+
181
+ await expect ( page . getByRole ( 'button' , { name : 'new-file.js' } ) ) . toBeVisible ( ) ;
182
+ await expect ( page . getByRole ( 'button' , { name : 'new-folder' } ) ) . toBeVisible ( ) ;
183
+
184
+ // verify that files are present on file system via terminal
185
+ for ( const [ directory , folder ] of [
186
+ [ './' , 'new-file.js' ] ,
187
+ [ './first-level/second-level/' , 'new-folder' ] ,
188
+ ] ) {
189
+ await terminal . fill ( `clear; ls ${ directory } ` ) ;
190
+ await terminal . press ( 'Enter' ) ;
191
+
192
+ await expect ( terminalOutput ) . toContainText ( folder , { useInnerText : true } ) ;
193
+ }
194
+ } ) ;
195
+
196
+ test ( 'user cannot create files or folders in disallowed directories' , async ( { page } ) => {
197
+ await page . goto ( `${ BASE_URL } /allow-edits-glob` ) ;
198
+ await expect ( page . getByRole ( 'heading' , { level : 1 , name : 'File Tree test - Allow Edits Glob' } ) ) . toBeVisible ( ) ;
199
+
200
+ // wait for terminal to start
201
+ const terminalOutput = page . getByRole ( 'tabpanel' , { name : 'Terminal' } ) ;
202
+ await expect ( terminalOutput ) . toContainText ( '~/tutorial' , { useInnerText : true } ) ;
203
+
204
+ for ( const [ name , type ] of [
205
+ [ 'new-file.js' , 'file' ] ,
206
+ [ 'new-folder' , 'folder' ] ,
207
+ ] as const ) {
208
+ await page . getByRole ( 'button' , { name : 'first-level' } ) . click ( { button : 'right' } ) ;
209
+ await page . getByRole ( 'menuitem' , { name : `Create ${ type } ` } ) . click ( ) ;
210
+
211
+ await page . locator ( '*:focus' ) . fill ( name ) ;
212
+ await page . locator ( '*:focus' ) . press ( 'Enter' ) ;
213
+
214
+ const dialog = page . getByRole ( 'dialog' , { name : 'This action is not allowed' } ) ;
215
+
216
+ await expect ( dialog . getByText ( 'Created files and folders must match following patterns:' ) ) . toBeVisible ( ) ;
217
+ await expect ( dialog . getByRole ( 'listitem' ) . nth ( 0 ) ) . toHaveText ( '/*' ) ;
218
+ await expect ( dialog . getByRole ( 'listitem' ) . nth ( 1 ) ) . toHaveText ( '/first-level/allowed-filename-only.js' ) ;
219
+ await expect ( dialog . getByRole ( 'listitem' ) . nth ( 2 ) ) . toHaveText ( '**/second-level/**' ) ;
220
+
221
+ await dialog . getByRole ( 'button' , { name : 'OK' } ) . click ( ) ;
222
+ await expect ( dialog ) . not . toBeVisible ( ) ;
223
+ }
224
+ } ) ;
0 commit comments