Skip to content

Commit e4447ba

Browse files
authored
fix: moving from svelte4 to svelte5 (#145)
* fix: moving from svelte4 to svelte5 also updated tests * fix: unification of auth component, also removed most try-catches cause errors are caought by api interceptors * fix: added unit tests for svelte components, changed/extended e2e for frontend * fix: code duplication in tests * fix: detected issues * fix: frontend lint * fix: tests
1 parent cc1564e commit e4447ba

65 files changed

Lines changed: 3393 additions & 2321 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/reference/openapi.json

Lines changed: 4 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,28 +1859,6 @@
18591859
}
18601860
}
18611861
},
1862-
"/api/v1/events/health": {
1863-
"get": {
1864-
"tags": [
1865-
"sse"
1866-
],
1867-
"summary": "Sse Health",
1868-
"description": "Get SSE service health status.",
1869-
"operationId": "sse_health_api_v1_events_health_get",
1870-
"responses": {
1871-
"200": {
1872-
"description": "Successful Response",
1873-
"content": {
1874-
"application/json": {
1875-
"schema": {
1876-
"$ref": "#/components/schemas/SSEHealthResponse"
1877-
}
1878-
}
1879-
}
1880-
}
1881-
}
1882-
}
1883-
},
18841862
"/api/v1/events/executions/{execution_id}/events": {
18851863
"get": {
18861864
"tags": [
@@ -9068,14 +9046,7 @@
90689046
"title": "Exit Code"
90699047
},
90709048
"error_type": {
9071-
"anyOf": [
9072-
{
9073-
"$ref": "#/components/schemas/ExecutionErrorType"
9074-
},
9075-
{
9076-
"type": "null"
9077-
}
9078-
]
9049+
"$ref": "#/components/schemas/ExecutionErrorType"
90799050
},
90809051
"error_message": {
90819052
"type": "string",
@@ -9896,7 +9867,6 @@
98969867
"saga_commands",
98979868
"dead_letter_queue",
98989869
"dlq_events",
9899-
"event_bus_stream",
99009870
"websocket_events"
99019871
],
99029872
"title": "KafkaTopic",
@@ -13104,10 +13074,7 @@
1310413074
"enum": [
1310513075
"connected",
1310613076
"subscribed",
13107-
"heartbeat",
13108-
"shutdown",
13109-
"status",
13110-
"error"
13077+
"status"
1311113078
],
1311213079
"title": "SSEControlEvent",
1311313080
"description": "Control events for execution SSE streams (not from Kafka)."
@@ -13178,31 +13145,7 @@
1317813145
}
1317913146
],
1318013147
"title": "Message",
13181-
"description": "Human-readable message (heartbeat, shutdown)"
13182-
},
13183-
"grace_period": {
13184-
"anyOf": [
13185-
{
13186-
"type": "integer"
13187-
},
13188-
{
13189-
"type": "null"
13190-
}
13191-
],
13192-
"title": "Grace Period",
13193-
"description": "Shutdown grace period in seconds"
13194-
},
13195-
"error": {
13196-
"anyOf": [
13197-
{
13198-
"type": "string"
13199-
},
13200-
{
13201-
"type": "null"
13202-
}
13203-
],
13204-
"title": "Error",
13205-
"description": "Error message (error event)"
13148+
"description": "Human-readable message (subscribed event)"
1320613149
},
1320713150
"status": {
1320813151
"anyOf": [
@@ -13294,71 +13237,6 @@
1329413237
"title": "SSEExecutionEventData",
1329513238
"description": "Typed model for SSE execution stream event payload.\n\nThis represents the JSON data sent inside each SSE message for execution streams.\nAll fields except event_type and execution_id are optional since different\nevent types carry different data."
1329613239
},
13297-
"SSEHealthResponse": {
13298-
"properties": {
13299-
"status": {
13300-
"$ref": "#/components/schemas/SSEHealthStatus",
13301-
"description": "Health status: healthy or draining"
13302-
},
13303-
"kafka_enabled": {
13304-
"type": "boolean",
13305-
"title": "Kafka Enabled",
13306-
"description": "Whether Kafka features are enabled",
13307-
"default": true
13308-
},
13309-
"active_connections": {
13310-
"type": "integer",
13311-
"title": "Active Connections",
13312-
"description": "Total number of active SSE connections"
13313-
},
13314-
"active_executions": {
13315-
"type": "integer",
13316-
"title": "Active Executions",
13317-
"description": "Number of executions being monitored"
13318-
},
13319-
"active_consumers": {
13320-
"type": "integer",
13321-
"title": "Active Consumers",
13322-
"description": "Number of active Kafka consumers"
13323-
},
13324-
"max_connections_per_user": {
13325-
"type": "integer",
13326-
"title": "Max Connections Per User",
13327-
"description": "Maximum connections allowed per user"
13328-
},
13329-
"shutdown": {
13330-
"$ref": "#/components/schemas/ShutdownStatusResponse",
13331-
"description": "Shutdown status information"
13332-
},
13333-
"timestamp": {
13334-
"type": "string",
13335-
"format": "date-time",
13336-
"title": "Timestamp",
13337-
"description": "Health check timestamp"
13338-
}
13339-
},
13340-
"type": "object",
13341-
"required": [
13342-
"status",
13343-
"active_connections",
13344-
"active_executions",
13345-
"active_consumers",
13346-
"max_connections_per_user",
13347-
"shutdown",
13348-
"timestamp"
13349-
],
13350-
"title": "SSEHealthResponse",
13351-
"description": "Response model for SSE health check."
13352-
},
13353-
"SSEHealthStatus": {
13354-
"type": "string",
13355-
"enum": [
13356-
"healthy",
13357-
"draining"
13358-
],
13359-
"title": "SSEHealthStatus",
13360-
"description": "Health status for SSE service."
13361-
},
1336213240
"SagaCancellationResponse": {
1336313241
"properties": {
1336413242
"success": {
@@ -14782,57 +14660,6 @@
1478214660
"title": "SettingsHistoryResponse",
1478314661
"description": "Response model for settings history (limited snapshot of recent changes)"
1478414662
},
14785-
"ShutdownStatusResponse": {
14786-
"properties": {
14787-
"phase": {
14788-
"type": "string",
14789-
"title": "Phase",
14790-
"description": "Current shutdown phase"
14791-
},
14792-
"initiated": {
14793-
"type": "boolean",
14794-
"title": "Initiated",
14795-
"description": "Whether shutdown has been initiated"
14796-
},
14797-
"complete": {
14798-
"type": "boolean",
14799-
"title": "Complete",
14800-
"description": "Whether shutdown is complete"
14801-
},
14802-
"active_connections": {
14803-
"type": "integer",
14804-
"title": "Active Connections",
14805-
"description": "Number of active connections"
14806-
},
14807-
"draining_connections": {
14808-
"type": "integer",
14809-
"title": "Draining Connections",
14810-
"description": "Number of connections being drained"
14811-
},
14812-
"duration": {
14813-
"anyOf": [
14814-
{
14815-
"type": "number"
14816-
},
14817-
{
14818-
"type": "null"
14819-
}
14820-
],
14821-
"title": "Duration",
14822-
"description": "Duration of shutdown in seconds"
14823-
}
14824-
},
14825-
"type": "object",
14826-
"required": [
14827-
"phase",
14828-
"initiated",
14829-
"complete",
14830-
"active_connections",
14831-
"draining_connections"
14832-
],
14833-
"title": "ShutdownStatusResponse",
14834-
"description": "Response model for shutdown status."
14835-
},
1483614663
"SortOrder": {
1483714664
"type": "string",
1483814665
"enum": [
@@ -15984,6 +15811,7 @@
1598415811
"title": "Reason"
1598515812
}
1598615813
},
15814+
"additionalProperties": true,
1598715815
"type": "object",
1598815816
"required": [
1598915817
"event_id",

frontend/e2e/editor.spec.ts

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { test, expect, runExampleAndExecute, expectToastVisible, describeAuthRequired } from './fixtures';
1+
import {
2+
test, expect, runExampleAndExecute, expectToastVisible, describeAuthRequired,
3+
loadExampleScript, openScriptOptions, saveScriptAs, expandSavedScripts,
4+
} from './fixtures';
25

36
const PATH = '/editor';
47

@@ -35,10 +38,7 @@ test.describe('Editor Page', () => {
3538

3639
test('shows file actions when panel opened', async ({ userPage }) => {
3740
await userPage.goto(PATH);
38-
// Use the button's accessible name from sr-only text
39-
const optionsToggle = userPage.getByRole('button', { name: 'Toggle Script Options' });
40-
await expect(optionsToggle).toBeVisible();
41-
await optionsToggle.click();
41+
await openScriptOptions(userPage);
4242
await expect(userPage.getByText('File Actions')).toBeVisible();
4343
await expect(userPage.getByRole('button', { name: /New/i })).toBeVisible();
4444
await expect(userPage.getByRole('button', { name: /Upload/i })).toBeVisible();
@@ -48,10 +48,8 @@ test.describe('Editor Page', () => {
4848

4949
test('can load example script', async ({ userPage }) => {
5050
await userPage.goto(PATH);
51-
await userPage.getByRole('button', { name: /Example/i }).click();
52-
const editor = userPage.locator('.cm-content');
53-
await expect(editor).not.toBeEmpty({ timeout: 3000 });
54-
const content = await editor.textContent();
51+
await loadExampleScript(userPage);
52+
const content = await userPage.locator('.cm-content').textContent();
5553
expect(content).toBeTruthy();
5654
expect(content!.length).toBeGreaterThan(0);
5755
});
@@ -97,8 +95,7 @@ test.describe('Editor Execution', () => {
9795

9896
test('run button is disabled during execution', async ({ userPage }) => {
9997
await userPage.goto(PATH);
100-
await userPage.getByRole('button', { name: /Example/i }).click();
101-
await expect(userPage.locator('.cm-content')).not.toBeEmpty({ timeout: 3000 });
98+
await loadExampleScript(userPage);
10299
const runButton = userPage.getByRole('button', { name: /Run Script/i });
103100
await runButton.click();
104101
const executingButton = userPage.getByRole('button', { name: /Executing/i });
@@ -110,31 +107,71 @@ test.describe('Editor Execution', () => {
110107
test.describe('Editor Script Management', () => {
111108
test('can save script when authenticated', async ({ userPage }) => {
112109
await userPage.goto(PATH);
113-
await userPage.getByRole('button', { name: /Example/i }).click();
114-
await expect(userPage.locator('.cm-content')).not.toBeEmpty({ timeout: 3000 });
115-
await userPage.locator('#scriptNameInput').fill(`Test Script ${Date.now()}`);
116-
const optionsToggle = userPage.getByRole('button', { name: 'Toggle Script Options' });
117-
await optionsToggle.click();
118-
await userPage.locator('button[title="Save current script"]').click();
119-
await expectToastVisible(userPage);
110+
await saveScriptAs(userPage, `Test Script ${Date.now()}`);
120111
});
121112

122113
test('can create new script', async ({ userPage }) => {
123114
await userPage.goto(PATH);
124-
await userPage.getByRole('button', { name: /Example/i }).click();
125-
await expect(userPage.locator('.cm-content')).not.toBeEmpty({ timeout: 3000 });
126-
const optionsToggle = userPage.getByRole('button', { name: 'Toggle Script Options' });
127-
await optionsToggle.click();
115+
await loadExampleScript(userPage);
116+
await openScriptOptions(userPage);
128117
await userPage.getByRole('button', { name: /New/i }).click();
129118
await expect(userPage.locator('#scriptNameInput')).toHaveValue('');
130119
});
131120

132121
test('shows saved scripts section when authenticated', async ({ userPage }) => {
133122
await userPage.goto(PATH);
134-
const optionsToggle = userPage.getByRole('button', { name: 'Toggle Script Options' });
135-
await optionsToggle.click();
123+
await openScriptOptions(userPage);
136124
await expect(userPage.getByRole('heading', { name: 'Saved Scripts' })).toBeVisible();
137125
});
126+
127+
test('can load a previously saved script', async ({ userPage }) => {
128+
await userPage.goto(PATH);
129+
const scriptName = `Load Test ${Date.now()}`;
130+
await saveScriptAs(userPage, scriptName);
131+
132+
// Create new script to clear state
133+
await userPage.getByRole('button', { name: /New/i }).click();
134+
await expect(userPage.locator('#scriptNameInput')).toHaveValue('');
135+
136+
// Expand the saved scripts list to find the saved script
137+
await expandSavedScripts(userPage);
138+
139+
const savedScript = userPage.locator(`text="${scriptName}"`).first();
140+
await expect(savedScript).toBeVisible({ timeout: 3000 });
141+
await savedScript.click();
142+
await expectToastVisible(userPage);
143+
await expect(userPage.locator('#scriptNameInput')).toHaveValue(scriptName);
144+
});
145+
146+
test('can delete a saved script', async ({ userPage }) => {
147+
await userPage.goto(PATH);
148+
const scriptName = `Delete Test ${Date.now()}`;
149+
await saveScriptAs(userPage, scriptName);
150+
151+
// Expand the saved scripts list to find the saved script
152+
await expandSavedScripts(userPage);
153+
154+
const scriptRow = userPage.locator(`text="${scriptName}"`).first();
155+
await expect(scriptRow).toBeVisible({ timeout: 3000 });
156+
const deleteBtn = userPage.locator(`button[title="Delete ${scriptName}"]`);
157+
await expect(deleteBtn).toBeVisible({ timeout: 2000 });
158+
userPage.on('dialog', dialog => dialog.accept());
159+
await deleteBtn.click();
160+
await expectToastVisible(userPage);
161+
});
162+
163+
test('can export script as file', async ({ userPage }) => {
164+
await userPage.goto(PATH);
165+
await loadExampleScript(userPage);
166+
await userPage.locator('#scriptNameInput').fill('export-test');
167+
await openScriptOptions(userPage);
168+
169+
const [download] = await Promise.all([
170+
userPage.waitForEvent('download', { timeout: 5000 }),
171+
userPage.getByRole('button', { name: /Export/i }).click(),
172+
]);
173+
expect(download.suggestedFilename()).toContain('export-test');
174+
});
138175
});
139176

140177
describeAuthRequired(test, PATH);

0 commit comments

Comments
 (0)