Skip to content

Commit fa47e7e

Browse files
authored
e2e: misc flake fixes (plots, settings.json race condition, etc) (#10997)
### Summary Just wrangling a couple more flakes. ### QA Notes @:assistant
1 parent 97edcbb commit fa47e7e

File tree

8 files changed

+44
-24
lines changed

8 files changed

+44
-24
lines changed

test/e2e/fixtures/keybindings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,8 @@
105105
"key": "cmd+l a",
106106
"command": "notebook.debugCell" // Debugger: Debug Cell
107107
},
108+
{
109+
"key": "cmd+l c",
110+
"command": "workbench.action.positronPlots.clear" // Clear Plots
111+
}
108112
]

test/e2e/fixtures/test-setup/shared-utils.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import path from 'path';
77
import * as fs from 'fs';
88
import { constants, access, rm, mkdir, rename } from 'fs/promises';
9-
import { copyFixtureFile, MultiLogger, Application } from '../../infra';
9+
import { MultiLogger, Application } from '../../infra';
1010
import { SPEC_NAME, ROOT_PATH } from './constants';
1111

1212
let fixtureScreenshot: Buffer | undefined;
@@ -75,11 +75,11 @@ export async function copyUserSettings(userDir: string): Promise<string> {
7575
}
7676
}
7777

78-
// Overwrite fixtures/settings.json with the merged result
79-
fs.writeFileSync(settingsFile, JSON.stringify(mergedSettings, null, 2));
78+
// Write merged settings directly to user data directory (avoids race condition with shared fixture file)
79+
await mkdir(userDir, { recursive: true });
80+
const userSettingsFile = path.join(userDir, settingsFileName);
81+
fs.writeFileSync(userSettingsFile, JSON.stringify(mergedSettings, null, 2));
8082

81-
// Let existing helper copy settings.json into the user dir
82-
await copyFixtureFile(settingsFileName, userDir);
8383
return userDir;
8484
}
8585

test/e2e/pages/hotKeys.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,13 @@ export class HotKeys {
268268
await this.pressHotKeys('Cmd+J S', 'Debugger: Clear All Breakpoints');
269269
}
270270

271+
// -----------------------
272+
// --- Plots ---
273+
// -----------------------
274+
public clearPlots() {
275+
return this.pressHotKeys('Cmd+L C', 'Clear Plots');
276+
}
277+
271278
/**
272279
* Press the hotkeys.
273280
* Note: Supports multiple key sequences separated by spaces.

test/e2e/pages/positronAssistant.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,14 @@ export class Assistant {
105105
await expect(this.code.driver.page.locator(INSERT_NEW_FILE_BUTTON)).toHaveCount(1);
106106
}
107107

108-
async verifyManageModelsOptionVisible() {
108+
async pickModel() {
109109
await this.code.driver.page.locator(MODEL_PICKER_DROPDOWN).click();
110-
await expect(this.code.driver.page.locator(MANAGE_MODELS_ITEM)).toBeVisible();
111110
}
112111

112+
async expectManageModelsVisible() {
113+
await expect(this.code.driver.page.locator(MANAGE_MODELS_ITEM)).toBeVisible({ timeout: 3000 });
114+
};
115+
113116
async selectModelProvider(provider: string) {
114117
switch (provider.toLowerCase()) {
115118
case 'anthropic-api':

test/e2e/pages/terminal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export class Terminal {
6868

6969
return matches;
7070

71-
}).toPass({ timeout: timeout });
71+
}, 'Wait for terminal text').toPass({ timeout: timeout });
7272

7373
return [];
7474
}

test/e2e/tests/console/console-python.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ test.describe('Console Pane: Alternate Python', { tag: [tags.WEB, tags.CONSOLE,
1717

1818
test('Verify alternate python can skip bundled ipykernel', async ({ app, sessions }) => {
1919
await sessions.start('pythonAlt');
20+
await sessions.clearConsoleAllSessions();
2021
await app.workbench.console.executeCode('Python', 'import ipykernel; ipykernel.__file__');
2122
await app.workbench.console.waitForConsoleContents('site-packages');
2223
await sessions.deleteAll();

test/e2e/tests/plots/plots.test.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ test.describe('Plots', { tag: [tags.PLOTS, tags.EDITOR] }, () => {
2828
test.afterEach(async function ({ app, hotKeys }) {
2929
await hotKeys.fullSizeSecondarySidebar();
3030
await expect(async () => {
31-
await app.workbench.plots.clearPlots();
32-
await app.workbench.plots.waitForNoPlots({ timeout: 5000 });
31+
await hotKeys.clearPlots();
32+
await app.workbench.plots.waitForNoPlots({ timeout: 3000 });
3333
}).toPass({ timeout: 15000 });
3434
});
3535

@@ -39,7 +39,7 @@ test.describe('Plots', { tag: [tags.PLOTS, tags.EDITOR] }, () => {
3939

4040
test('Python - Verify basic plot functionality - Dynamic Plot', {
4141
tag: [tags.WEB, tags.WIN, tags.CRITICAL]
42-
}, async function ({ app, logger, headless }, testInfo) {
42+
}, async function ({ app, logger, headless, hotKeys }, testInfo) {
4343
// modified snippet from https://www.geeksforgeeks.org/python-pandas-dataframe/
4444
logger.log('Sending code to console');
4545
await app.workbench.console.executeCode('Python', pythonDynamicPlot);
@@ -73,10 +73,10 @@ test.describe('Plots', { tag: [tags.PLOTS, tags.EDITOR] }, () => {
7373
await app.workbench.quickaccess.runCommand('workbench.action.closeAllEditors');
7474
});
7575

76-
await app.workbench.layouts.enterLayout('fullSizedAuxBar');
77-
await app.workbench.plots.clearPlots();
78-
await app.workbench.layouts.enterLayout('stacked');
79-
await app.workbench.plots.waitForNoPlots();
76+
await expect(async () => {
77+
await hotKeys.clearPlots();
78+
await app.workbench.plots.waitForNoPlots({ timeout: 3000 });
79+
}).toPass({ timeout: 15000 });
8080
});
8181

8282
test('Python - Verify basic plot functionality - Static Plot', {
@@ -341,9 +341,10 @@ test.describe('Plots', { tag: [tags.PLOTS, tags.EDITOR] }, () => {
341341
});
342342

343343
test.afterEach(async function ({ app, hotKeys }) {
344-
await hotKeys.fullSizeSecondarySidebar();
345-
await app.workbench.plots.clearPlots();
346-
await app.workbench.plots.waitForNoPlots();
344+
await expect(async () => {
345+
await hotKeys.clearPlots();
346+
await app.workbench.plots.waitForNoPlots({ timeout: 3000 });
347+
}).toPass({ timeout: 15000 });
347348
});
348349

349350
test.afterAll(async function ({ cleanup }) {
@@ -352,7 +353,7 @@ test.describe('Plots', { tag: [tags.PLOTS, tags.EDITOR] }, () => {
352353

353354
test('R - Verify basic plot functionality', {
354355
tag: [tags.WEB, tags.WIN, tags.CRITICAL]
355-
}, async function ({ app, logger, headless }, testInfo) {
356+
}, async function ({ app, logger, headless, hotKeys }, testInfo) {
356357
logger.log('Sending code to console');
357358
await app.workbench.console.executeCode('R', rBasicPlot);
358359
await app.workbench.plots.waitForCurrentPlot();
@@ -385,10 +386,10 @@ test.describe('Plots', { tag: [tags.PLOTS, tags.EDITOR] }, () => {
385386
await app.workbench.quickaccess.runCommand('workbench.action.closeAllEditors');
386387
});
387388

388-
await app.workbench.layouts.enterLayout('fullSizedAuxBar');
389-
await app.workbench.plots.clearPlots();
390-
await app.workbench.layouts.enterLayout('stacked');
391-
await app.workbench.plots.waitForNoPlots();
389+
await expect(async () => {
390+
await hotKeys.clearPlots();
391+
await app.workbench.plots.waitForNoPlots({ timeout: 3000 });
392+
}).toPass({ timeout: 15000 });
392393
});
393394

394395
test('R - Verify opening plot in new window', { tag: [tags.WEB, tags.WIN, tags.PLOTS, tags.CRITICAL] }, async function ({ app }) {

test/e2e/tests/positron-assistant/positron-assistant.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,11 @@ test.describe('Positron Assistant Chat Editing', { tag: [tags.WIN, tags.ASSISTAN
169169
});
170170

171171
test('Verify Manage Models is available', { tag: [tags.SOFT_FAIL] }, async function ({ app }) {
172-
await app.workbench.assistant.verifyManageModelsOptionVisible();
172+
// sometimes the menu closes due to language model loading (?), so retry
173+
await expect(async () => {
174+
await app.workbench.assistant.pickModel();
175+
await app.workbench.assistant.expectManageModelsVisible();
176+
}).toPass({ timeout: 30000 });
173177
});
174178
});
175179

0 commit comments

Comments
 (0)