|
| 1 | +// Components |
1 | 2 | import { VTextField } from '../VTextField'
|
| 3 | +import { VBtn } from '@/components/VBtn' |
| 4 | +import { VMenu } from '@/components/VMenu' |
2 | 5 |
|
3 | 6 | // Utilities
|
4 |
| -import { generate, render, userEvent } from '@test' |
| 7 | +import { commands, generate, render, screen, userEvent, wait } from '@test' |
5 | 8 | import { cloneVNode } from 'vue'
|
6 | 9 |
|
7 | 10 | const variants = ['underlined', 'outlined', 'filled', 'solo', 'plain'] as const
|
@@ -60,6 +63,46 @@ describe('VTextField', () => {
|
60 | 63 | expect(element).toHaveTextContent('Error!')
|
61 | 64 | })
|
62 | 65 |
|
| 66 | + it('does not trigger infinite loop when autofilled by password manager', async () => { |
| 67 | + render(() => ( |
| 68 | + <div> |
| 69 | + <VTextField label="username" name="username" type="email" /> |
| 70 | + <VTextField label="password" name="password" type="password" /> |
| 71 | + <VBtn> |
| 72 | + Some button |
| 73 | + <VMenu activator="parent"> |
| 74 | + <div class="my-menu-content">Some text in menu</div> |
| 75 | + </VMenu> |
| 76 | + </VBtn> |
| 77 | + </div> |
| 78 | + )) |
| 79 | + |
| 80 | + const input1 = screen.getByCSS('input[name="username"]') as HTMLInputElement |
| 81 | + const input2 = screen.getByCSS('input[name="password"]') as HTMLInputElement |
| 82 | + |
| 83 | + await commands.abortAfter(5000, 'VTextField infinite loop detection') |
| 84 | + |
| 85 | + input1.focus() |
| 86 | + input1.value = 'my username' |
| 87 | + input1.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertFromPaste' })) |
| 88 | + input1.dispatchEvent(new Event('change', { bubbles: true })) |
| 89 | + |
| 90 | + input2.focus() |
| 91 | + input2.value = 'my password' |
| 92 | + input2.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertFromPaste' })) |
| 93 | + input2.dispatchEvent(new Event('change', { bubbles: true })) |
| 94 | + |
| 95 | + await wait(100) |
| 96 | + const button = screen.getByCSS('.v-btn') |
| 97 | + await userEvent.click(button) |
| 98 | + await wait(100) |
| 99 | + |
| 100 | + const menuContent = screen.getByCSS('.my-menu-content') |
| 101 | + expect(menuContent).toBeVisible() |
| 102 | + |
| 103 | + await commands.clearAbortTimeout() |
| 104 | + }) |
| 105 | + |
63 | 106 | it('handles multiple options in validate-on prop', async () => {
|
64 | 107 | const rule = vi.fn(v => v?.length > 5 || 'Error!')
|
65 | 108 |
|
|
0 commit comments