@@ -20,16 +20,16 @@ describe('EnvironmentOptions', () => {
2020 describe('getEnvironmentOptions', () => {
2121 it('should return default options when no URL params', () => {
2222 // Arrange
23- const url = new URL('http://localhost');
23+ const url = new URL('http://localhost')
2424
2525 // Act
26- const result = getEnvironmentOptions(url);
26+ const result = getEnvironmentOptions(url)
2727
2828 // Assert
29- expect(result.theme).toBe('dark');
30- });
31- });
32- });
29+ expect(result.theme).toBe('dark')
30+ })
31+ })
32+ })
3333```
3434
3535### Test All Exported Functions
@@ -40,22 +40,22 @@ Every exported function should have tests:
4040// ✅ Good - testing public API
4141describe('orderFields', () => {
4242 it('should order object fields alphabetically', () => {
43- const input = { z: 1, a: 2, m: 3 };
44- const result = orderFields(input);
45- expect(Object.keys(result)).toEqual(['a', 'm', 'z']);
46- });
43+ const input = { z: 1, a: 2, m: 3 }
44+ const result = orderFields(input)
45+ expect(Object.keys(result)).toEqual(['a', 'm', 'z'])
46+ })
4747
4848 it('should handle nested objects', () => {
49- const input = { outer: { z: 1, a: 2 } };
50- const result = orderFields(input);
51- expect(Object.keys(result.outer)).toEqual(['a', 'z']);
52- });
49+ const input = { outer: { z: 1, a: 2 } }
50+ const result = orderFields(input)
51+ expect(Object.keys(result.outer)).toEqual(['a', 'z'])
52+ })
5353
5454 it('should handle empty objects', () => {
55- const result = orderFields({});
56- expect(result).toEqual({});
57- });
58- });
55+ const result = orderFields({})
56+ expect(result).toEqual({})
57+ })
58+ })
5959```
6060
6161### Test Edge Cases
@@ -66,25 +66,25 @@ Test boundary conditions and error scenarios:
6666// ✅ Good - testing edge cases
6767describe('parseJson', () => {
6868 it('should handle valid JSON', () => {
69- const result = parseJson('{"key": "value"}');
70- expect(result).toEqual({ key: 'value' });
71- });
69+ const result = parseJson('{"key": "value"}')
70+ expect(result).toEqual({ key: 'value' })
71+ })
7272
7373 it('should handle invalid JSON', () => {
74- const result = parseJson('invalid');
75- expect(result).toBeNull();
76- });
74+ const result = parseJson('invalid')
75+ expect(result).toBeNull()
76+ })
7777
7878 it('should handle empty string', () => {
79- const result = parseJson('');
80- expect(result).toBeNull();
81- });
79+ const result = parseJson('')
80+ expect(result).toBeNull()
81+ })
8282
8383 it('should handle null input', () => {
84- const result = parseJson(null as unknown as string);
85- expect(result).toBeNull();
86- });
87- });
84+ const result = parseJson(null as unknown as string)
85+ expect(result).toBeNull()
86+ })
87+ })
8888```
8989
9090### Avoid False Positive Tests
@@ -95,26 +95,26 @@ Ensure assertions always run:
9595// ❌ False positive risk - passes if function doesn't throw
9696it('should throw on error', async () => {
9797 try {
98- await functionThatShouldThrow();
98+ await functionThatShouldThrow()
9999 } catch (error) {
100- expect(error).toBeInstanceOf(Error);
100+ expect(error).toBeInstanceOf(Error)
101101 }
102- });
102+ })
103103
104104// ✅ Correct - fails if assertions don't run
105105it('should throw on error', async () => {
106- expect.assertions(1);
106+ expect.assertions(1)
107107 try {
108- await functionThatShouldThrow();
108+ await functionThatShouldThrow()
109109 } catch (error) {
110- expect(error).toBeInstanceOf(Error);
110+ expect(error).toBeInstanceOf(Error)
111111 }
112- });
112+ })
113113
114114// ✅ Better - use expect().rejects
115115it('should throw on error', async () => {
116- await expect(functionThatShouldThrow()).rejects.toThrow();
117- });
116+ await expect(functionThatShouldThrow()).rejects.toThrow()
117+ })
118118```
119119
120120## E2E Testing with Playwright
@@ -123,58 +123,58 @@ it('should throw on error', async () => {
123123
124124```typescript
125125// e2e/page.spec.ts
126- import { test, expect } from '@playwright/test';
126+ import { test, expect } from '@playwright/test'
127127
128128test.describe('Home Page', () => {
129129 test.beforeEach(async ({ page }) => {
130- await page.goto('/');
131- });
130+ await page.goto('/')
131+ })
132132
133133 test('should display editor', async ({ page }) => {
134- await expect(page.locator('.monaco-editor')).toBeVisible();
135- });
134+ await expect(page.locator('.monaco-editor')).toBeVisible()
135+ })
136136
137137 test('should format JSON on button click', async ({ page }) => {
138- const editor = page.locator('.monaco-editor');
139- await editor.fill('{"z":1,"a":2}');
140-
141- await page.click('button:has-text("Format")');
142-
138+ const editor = page.locator('.monaco-editor')
139+ await editor.fill('{"z":1,"a":2}')
140+
141+ await page.click('button:has-text("Format")')
142+
143143 // Verify formatted output
144- await expect(editor).toContainText('"a": 2');
145- });
146- });
144+ await expect(editor).toContainText('"a": 2')
145+ })
146+ })
147147```
148148
149149### Visual Regression Testing
150150
151151```typescript
152152// ✅ Good - visual snapshot testing
153153test('should match visual snapshot', async ({ page }) => {
154- await page.goto('/');
155- await expect(page).toHaveScreenshot('home-content.png');
156- });
154+ await page.goto('/')
155+ await expect(page).toHaveScreenshot('home-content.png')
156+ })
157157
158158test('should match title snapshot', async ({ page }) => {
159- await page.goto('/');
160- const title = page.locator('h1');
161- await expect(title).toHaveScreenshot('title.png');
162- });
159+ await page.goto('/')
160+ const title = page.locator('h1')
161+ await expect(title).toHaveScreenshot('title.png')
162+ })
163163```
164164
165165### Waiting for Elements
166166
167167```typescript
168168// ✅ Good - wait for element to be ready
169169test('should load editor', async ({ page }) => {
170- await page.goto('/');
171-
170+ await page.goto('/')
171+
172172 // Wait for Monaco editor to initialize
173- await page.waitForSelector('.monaco-editor', { state: 'visible' });
174-
173+ await page.waitForSelector('.monaco-editor', { state: 'visible' })
174+
175175 // Now interact with the editor
176- await page.click('.monaco-editor');
177- });
176+ await page.click('.monaco-editor')
177+ })
178178```
179179
180180## Test Coverage
@@ -187,7 +187,7 @@ test('should load editor', async ({ page }) => {
187187
188188```bash
189189# Run unit tests with coverage
190- yarn test:unit --coverage
190+ yarn test --coverage
191191
192192# Run E2E tests
193193yarn test:e2e
@@ -199,13 +199,13 @@ yarn test:e2e
199199
200200```bash
201201# Unit tests
202- yarn test:unit
202+ yarn test
203203
204204# E2E tests
205205yarn test:e2e
206206
207207# All tests
208- yarn test:unit && yarn test:e2e
208+ yarn test && yarn test:e2e
209209```
210210
211211## Summary
@@ -231,4 +231,4 @@ yarn test:unit && yarn test:e2e
231231
232232- Unit Tests: `vitest`
233233- E2E Tests: `playwright`
234- - Commands: `yarn test:unit `, `yarn test:e2e`
234+ - Commands: `yarn test`, `yarn test:e2e`
0 commit comments