@@ -54,6 +54,94 @@ electron . --enable-mcp-introspection --remote-debugging-port=9223
54543 . ** Include screenshots** - Visual verification is required for UI changes
55554 . ** Handle asynchronous operations properly** - This is an MQTT message queue tool
5656
57+ ### Best Practices for UI Tests
58+
59+ #### 1. Use Given-When-Then Pattern
60+ Structure tests with clear Given-When-Then comments to make them readable:
61+
62+ ``` typescript
63+ it (' Given a JSON message sent to topic foo/bar/baz, the tree should display nested topics' , async function () {
64+ // Given: Mock MQTT publishes JSON to foo/bar/baz
65+ // When: We wait for the topic to appear in the tree
66+ // Then: Topic hierarchy should be visible (foo -> bar -> baz)
67+ })
68+ ```
69+
70+ #### 2. Wait for Elements, Don't Use Fixed Delays
71+ Prefer ` waitFor ` over ` sleep ` whenever possible:
72+
73+ ``` typescript
74+ // ✓ Good: Wait for specific element
75+ const topic = await page .locator (' span[data-test-topic="kitchen"]' )
76+ await topic .waitFor ({ state: ' visible' , timeout: 5000 })
77+
78+ // ✗ Bad: Fixed delay without verification
79+ await sleep (5000 )
80+ ```
81+
82+ #### 3. Use Meaningful Assertions
83+ Every test should have explicit assertions that verify the expected state:
84+
85+ ``` typescript
86+ // ✓ Good: Explicit assertion with meaningful message
87+ const treeNodes = await page .locator (' [class*="TreeNode"]' )
88+ const count = await treeNodes .count ()
89+ expect (count ).to .be .greaterThan (0 , ' Topic tree should contain nodes' )
90+
91+ // ✗ Bad: No assertion, only screenshot
92+ await page .screenshot ({ path: ' test.png' })
93+ ```
94+
95+ #### 4. Test Data-Driven Scenarios
96+ Write tests that describe the data flow:
97+
98+ ``` typescript
99+ it (' Given messages sent to livingroom/lamp/state and livingroom/lamp/brightness, both should appear under livingroom/lamp' , async function () {
100+ // Test implementation verifies the specific data flow
101+ })
102+ ```
103+
104+ #### 5. Use Data Test Attributes
105+ Leverage ` data-test-* ` attributes for reliable selectors:
106+
107+ ``` typescript
108+ // ✓ Good: Use data-test attributes
109+ const topic = await page .locator (' span[data-test-topic="kitchen"]' )
110+
111+ // ⚠ Acceptable: Use role/text when data attributes aren't available
112+ const button = await page .locator (' //button/span[contains(text(),"Connect")]' )
113+
114+ // ✗ Bad: Rely on CSS classes that may change
115+ const topic = await page .locator (' .MuiTreeItem-label' )
116+ ```
117+
118+ #### 6. Verify Multiple Aspects
119+ Test should verify both state and UI:
120+
121+ ``` typescript
122+ // Verify the action completed
123+ const isVisible = await disconnectButton .isVisible ()
124+ expect (isVisible ).to .be .true
125+
126+ // Capture screenshot for visual verification
127+ await page .screenshot ({ path: ' test-screenshot-connection.png' })
128+ ```
129+
130+ #### 7. Handle MQTT Asynchronous Nature
131+ Account for message propagation time:
132+
133+ ``` typescript
134+ // Publish message
135+ await mockClient .publish (' topic/name' , ' value' )
136+
137+ // Wait for UI to update
138+ await page .locator (` text="value" ` ).waitFor ({ timeout: 5000 })
139+
140+ // Verify state
141+ const value = await page .textContent (' .message-value' )
142+ expect (value ).toBe (' value' )
143+ ```
144+
57145### Handling MQTT Asynchronous Operations
58146
59147MQTT is inherently asynchronous. When writing tests:
0 commit comments