experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 181 lines 5.2 kB view raw
1/** 2 * Browser Extension Popup Tests 3 * 4 * Tests for the command bar popup (popup.html/popup.js). 5 * Run with: BROWSER=chrome yarn test:extension:browser 6 */ 7 8import { test, expect } from '@playwright/test'; 9import { getSharedExtension, ExtensionApp } from '../fixtures/extension-app'; 10import { 11 waitForCommandInput, 12 typeCommand, 13 tabComplete, 14 executeCommand, 15 getTypedText, 16 getDisplayText, 17 isPlaceholderShown, 18 getTypedPortion, 19} from '../helpers/extension-utils'; 20import { Page } from '@playwright/test'; 21 22let ext: ExtensionApp; 23let popup: Page; 24 25test.beforeAll(async () => { 26 ext = await getSharedExtension(); 27}); 28 29// Don't close shared extension - let Playwright handle cleanup 30// This allows multiple test files to share the same browser instance 31 32test.beforeEach(async () => { 33 // Open a fresh popup for each test 34 popup = await ext.openPopup(); 35 await waitForCommandInput(popup); 36}); 37 38test.afterEach(async () => { 39 // Close the popup page 40 if (popup && !popup.isClosed()) { 41 await popup.close(); 42 } 43}); 44 45test.describe('Popup Command Bar', () => { 46 test('shows placeholder text when empty', async () => { 47 const placeholder = await isPlaceholderShown(popup); 48 expect(placeholder).toBe(true); 49 50 const displayText = await getDisplayText(popup); 51 expect(displayText).toBe('tag, note, or search...'); 52 }); 53 54 test('hides placeholder when typing', async () => { 55 await typeCommand(popup, 't'); 56 57 const placeholder = await isPlaceholderShown(popup); 58 expect(placeholder).toBe(false); 59 }); 60 61 test('autocompletes "t" to show "tag" suggestion', async () => { 62 await typeCommand(popup, 't'); 63 64 const displayText = await getDisplayText(popup); 65 // Should show typed 't' plus autocomplete suggestion 'ag' 66 expect(displayText).toBe('tag'); 67 68 const typedPortion = await getTypedPortion(popup); 69 expect(typedPortion).toBe('t'); 70 }); 71 72 test('autocompletes "n" to show "note" suggestion', async () => { 73 await typeCommand(popup, 'n'); 74 75 const displayText = await getDisplayText(popup); 76 expect(displayText).toBe('note'); 77 78 const typedPortion = await getTypedPortion(popup); 79 expect(typedPortion).toBe('n'); 80 }); 81 82 test('autocompletes "s" to show "search" suggestion', async () => { 83 await typeCommand(popup, 's'); 84 85 const displayText = await getDisplayText(popup); 86 expect(displayText).toBe('search'); 87 88 const typedPortion = await getTypedPortion(popup); 89 expect(typedPortion).toBe('s'); 90 }); 91 92 test('Tab completes the command', async () => { 93 await typeCommand(popup, 't'); 94 await tabComplete(popup); 95 96 const inputValue = await getTypedText(popup); 97 expect(inputValue).toBe('tag '); 98 }); 99 100 test('Tab completes "no" to "note "', async () => { 101 await typeCommand(popup, 'no'); 102 await tabComplete(popup); 103 104 const inputValue = await getTypedText(popup); 105 expect(inputValue).toBe('note '); 106 }); 107 108 test('Tab completes "se" to "search "', async () => { 109 await typeCommand(popup, 'se'); 110 await tabComplete(popup); 111 112 const inputValue = await getTypedText(popup); 113 expect(inputValue).toBe('search '); 114 }); 115 116 test('Enter with partial command completes it', async () => { 117 await typeCommand(popup, 't'); 118 await executeCommand(popup); 119 120 // Should autocomplete to "tag " since no args provided 121 const inputValue = await getTypedText(popup); 122 expect(inputValue).toBe('tag '); 123 }); 124 125 test('no autocomplete for non-matching input', async () => { 126 await typeCommand(popup, 'x'); 127 128 const displayText = await getDisplayText(popup); 129 // Should only show what was typed, no suggestion 130 expect(displayText).toBe('x'); 131 132 const typedPortion = await getTypedPortion(popup); 133 expect(typedPortion).toBe('x'); 134 }); 135 136 test('preserves case in typed text display', async () => { 137 await typeCommand(popup, 'TAG'); 138 139 // Typed text should be preserved as-is in display 140 const typedPortion = await getTypedPortion(popup); 141 expect(typedPortion).toBe('TAG'); 142 143 // But autocomplete still shows (matching is case-insensitive) 144 const displayText = await getDisplayText(popup); 145 // Display shows typed portion + rest of suggestion 146 expect(displayText).toContain('TAG'); 147 }); 148 149 test('no suggestion shown after space (args mode)', async () => { 150 await typeCommand(popup, 'tag '); 151 152 // After space, should just show what's typed 153 const displayText = await getDisplayText(popup); 154 expect(displayText).toBe('tag '); 155 }); 156 157 test('shows typed text with args', async () => { 158 await typeCommand(popup, 'tag foo, bar'); 159 160 const displayText = await getDisplayText(popup); 161 expect(displayText).toBe('tag foo, bar'); 162 163 const typedPortion = await getTypedPortion(popup); 164 expect(typedPortion).toBe('tag foo, bar'); 165 }); 166 167 test('input is focused on popup open', async () => { 168 const isFocused = await popup.evaluate(() => { 169 return document.activeElement?.id === 'command-input'; 170 }); 171 expect(isFocused).toBe(true); 172 }); 173 174 test('input accepts text input', async () => { 175 // Type using keyboard instead of fill 176 await popup.keyboard.type('tag test'); 177 178 const inputValue = await getTypedText(popup); 179 expect(inputValue).toBe('tag test'); 180 }); 181});