ai #1
@@ -70,4 +70,39 @@ test.describe('Environment Management', () => {
|
|||||||
await expect(page.locator('#environments')).toBeVisible();
|
await expect(page.locator('#environments')).toBeVisible();
|
||||||
await expect(page.locator('#environments option')).toHaveCount(2);
|
await expect(page.locator('#environments option')).toHaveCount(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should create multiple environments and switch between them', async ({ page }) => {
|
||||||
|
await page.goto('/');
|
||||||
|
await page.click('button:has-text("Create new")');
|
||||||
|
|
||||||
|
// Create env1
|
||||||
|
page.once('dialog', async dialog => {
|
||||||
|
await dialog.accept('env1');
|
||||||
|
});
|
||||||
|
await page.click('button.btn-success[title="Add environment"]');
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
|
// Create env2
|
||||||
|
page.once('dialog', async dialog => {
|
||||||
|
await dialog.accept('env2');
|
||||||
|
});
|
||||||
|
await page.click('button.btn-success[title="Add environment"]');
|
||||||
|
await page.waitForTimeout(500);
|
||||||
|
|
||||||
|
// Verify we have 3 envs (DEFAULT + env1 + env2)
|
||||||
|
await expect(page.locator('#environments option')).toHaveCount(3);
|
||||||
|
|
||||||
|
// Switch to each env and verify page doesn't crash
|
||||||
|
await page.locator('#environments').selectOption({ index: 0 });
|
||||||
|
await page.waitForTimeout(200);
|
||||||
|
await expect(page.locator('#environments')).toBeVisible();
|
||||||
|
|
||||||
|
await page.locator('#environments').selectOption('env1');
|
||||||
|
await page.waitForTimeout(200);
|
||||||
|
await expect(page.locator('#environments')).toBeVisible();
|
||||||
|
|
||||||
|
await page.locator('#environments').selectOption('env2');
|
||||||
|
await page.waitForTimeout(200);
|
||||||
|
await expect(page.locator('#environments')).toBeVisible();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
42
src/App.tsx
42
src/App.tsx
@@ -18,17 +18,18 @@ class AppState {
|
|||||||
static readonly Instance = new AppState();
|
static readonly Instance = new AppState();
|
||||||
|
|
||||||
public loadConfig(cfg: Config) {
|
public loadConfig(cfg: Config) {
|
||||||
this.envs = [...cfg.envs];
|
|
||||||
this.config = cfg;
|
this.config = cfg;
|
||||||
|
this.envs = cfg.envs; // Reference the same array as config
|
||||||
}
|
}
|
||||||
|
|
||||||
public addEnv(env: Env): number {
|
public addEnv(env: Env): number {
|
||||||
this.envs.push(env);
|
this.envs.push(env);
|
||||||
|
// Also update config.envs since they reference the same array
|
||||||
|
this.config.envs = this.envs;
|
||||||
return this.envs.length - 1;
|
return this.envs.length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async saveEnv(env: Env): Promise<number> {
|
public async saveEnv(env: Env): Promise<number> {
|
||||||
|
|
||||||
// Create a promise that resolves after 1 second
|
// Create a promise that resolves after 1 second
|
||||||
return await new Promise<number>((resolve) => {
|
return await new Promise<number>((resolve) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -41,6 +42,21 @@ class AppState {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public removeEnv(envId: number) {
|
||||||
|
const idx = this.envs.findIndex(x => x.id === envId);
|
||||||
|
if (idx > -1) {
|
||||||
|
this.envs.splice(idx, 1);
|
||||||
|
// Also update config.envs since they reference the same array
|
||||||
|
this.config.envs = this.envs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the internal envs reference to match React state
|
||||||
|
public syncEnvs(newEnvs: Env[]) {
|
||||||
|
this.envs = newEnvs;
|
||||||
|
this.config.envs = newEnvs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@@ -57,7 +73,12 @@ function App() {
|
|||||||
let idx = AppState.Instance.envs.findIndex(x => x.id === env.id);
|
let idx = AppState.Instance.envs.findIndex(x => x.id === env.id);
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
AppState.Instance.envs[idx] = env;
|
AppState.Instance.envs[idx] = env;
|
||||||
setEnvs([...AppState.Instance.envs]);
|
// Also update config.envs since they reference the same array
|
||||||
|
AppState.Instance.config.envs = AppState.Instance.envs;
|
||||||
|
const newEnvs = [...AppState.Instance.envs];
|
||||||
|
setEnvs(newEnvs);
|
||||||
|
AppState.Instance.syncEnvs(newEnvs); // Keep AppState in sync with React state
|
||||||
|
setConfig(AppState.Instance.config); // Trigger re-render for config
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then do the async save (for consistency with existing behavior)
|
// Then do the async save (for consistency with existing behavior)
|
||||||
@@ -70,16 +91,19 @@ function App() {
|
|||||||
|
|
||||||
function handleEnvAdded(env: Env): number {
|
function handleEnvAdded(env: Env): number {
|
||||||
const idx = AppState.Instance.addEnv(env);
|
const idx = AppState.Instance.addEnv(env);
|
||||||
setEnvs([...AppState.Instance.envs]);
|
const newEnvs = [...AppState.Instance.envs];
|
||||||
|
setEnvs(newEnvs);
|
||||||
|
AppState.Instance.syncEnvs(newEnvs); // Keep AppState in sync with React state
|
||||||
|
setConfig(AppState.Instance.config); // Trigger re-render for config
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEnvRemoved(envId: number) {
|
function handleEnvRemoved(envId: number) {
|
||||||
const idx = AppState.Instance.envs.findIndex(x => x.id === envId);
|
AppState.Instance.removeEnv(envId);
|
||||||
if (idx > -1) {
|
const newEnvs = [...AppState.Instance.envs];
|
||||||
AppState.Instance.envs.splice(idx, 1);
|
setEnvs(newEnvs);
|
||||||
setEnvs([...AppState.Instance.envs]);
|
AppState.Instance.syncEnvs(newEnvs); // Keep AppState in sync with React state
|
||||||
}
|
setConfig(AppState.Instance.config); // Trigger re-render for config
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user