Skip to content

Commit 9e65401

Browse files
committed
update e2e tests
1 parent e91d01d commit 9e65401

File tree

6 files changed

+68
-27
lines changed

6 files changed

+68
-27
lines changed

src/vs/platform/positronActionBar/browser/components/actionBarButton.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export type ActionBarButtonProps = {
3939
readonly maxTextWidth?: number;
4040
readonly align?: 'left' | 'right';
4141
readonly tooltip?: string | (() => string | undefined);
42+
readonly dataTestId?: string;
4243
readonly dropdownTooltip?: string | (() => string | undefined);
4344
readonly checked?: boolean;
4445
readonly disabled?: boolean;
@@ -92,7 +93,7 @@ export const ActionBarButton = forwardRef<
9293
*/
9394
const ActionBarButtonFace = () => {
9495
return (
95-
<div aria-hidden='true' className='action-bar-button-face'>
96+
<div aria-hidden='true' className='action-bar-button-face' data-testid={props.dataTestId}>
9697
{props.iconId && (
9798
<div
9899
className={positronClassNames(

src/vs/workbench/contrib/positronConsole/browser/components/actionBar.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ export const ActionBar = (props: ActionBarProps) => {
456456
<ActionBarButton
457457
align='right'
458458
ariaLabel={positronDeleteConsole}
459+
dataTestId='trash-session'
459460
disabled={!(canShutdown || canStart)}
460461
iconId='trash'
461462
tooltip={positronDeleteConsole}

test/e2e/pages/console.ts

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export class Console {
2727
barPowerButton: Locator;
2828
barRestartButton: Locator;
2929
barClearButton: Locator;
30+
barTrashButton: Locator;
3031
consoleRestartButton: Locator;
3132
activeConsole: Locator;
3233
suggestionList: Locator;
@@ -40,6 +41,7 @@ export class Console {
4041
this.barPowerButton = this.code.driver.page.getByLabel('Shutdown console');
4142
this.barRestartButton = this.code.driver.page.getByLabel('Restart console');
4243
this.barClearButton = this.code.driver.page.getByLabel('Clear console');
44+
this.barTrashButton = this.code.driver.page.getByTestId('trash-session');
4345
this.consoleRestartButton = this.code.driver.page.locator(CONSOLE_RESTART_BUTTON);
4446
this.activeConsole = this.code.driver.page.locator(ACTIVE_CONSOLE_INSTANCE);
4547
this.suggestionList = this.code.driver.page.locator(SUGGESTION_LIST);

test/e2e/pages/sessions.ts

+41-7
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class Sessions {
2525
private quickPick: SessionQuickPick;
2626
private trashButton: (sessionId: string) => Locator;
2727
private newConsoleButton: Locator;
28-
private restartButton: Locator;
28+
restartButton: Locator;
2929
private shutDownButton: Locator;
3030
sessionTabs: Locator;
3131
currentSessionTab: Locator;
@@ -211,13 +211,28 @@ export class Sessions {
211211
async deleteDisconnectedSessions() {
212212
await test.step('Delete all disconnected sessions', async () => {
213213
const sessionIds = await this.getAllSessionIds();
214+
const disconnectedSessions: string[] = [];
214215

216+
// Collect all disconnected session IDs
215217
for (const sessionId of sessionIds) {
216218
const status = await this.getStatus(sessionId);
217219
if (status === 'disconnected') {
218-
await this.delete(sessionId);
220+
disconnectedSessions.push(sessionId);
219221
}
220222
}
223+
224+
if (disconnectedSessions.length === 0) { return; } // Nothing to delete
225+
226+
// Delete all but the last one
227+
for (let i = 0; i < disconnectedSessions.length - 1; i++) {
228+
await this.delete(disconnectedSessions[i]);
229+
}
230+
231+
// Handle the last one separately because there is no tab list trash icon to click on
232+
const { state } = await this.getMetadata();
233+
if (state === 'disconnected' || state === 'exited') {
234+
await this.console.barTrashButton.click();
235+
}
221236
});
222237
}
223238

@@ -385,11 +400,22 @@ export class Sessions {
385400
* Note: Sessions that are disconnected are filtered out
386401
*/
387402
async getActiveSessions(): Promise<QuickPickSessionInfo[]> {
388-
const allSessions = await this.sessionTabs.all();
403+
const allSessionTabs = await this.sessionTabs.all();
404+
const metadataButtonExists = await this.metadataButton.isVisible();
405+
406+
if (allSessionTabs.length === 0) {
407+
// No active sessions
408+
if (!metadataButtonExists) { return []; }
409+
410+
// One session exists but the tab list is hidden
411+
const { path, name, state } = await this.getMetadata();
412+
return state === 'disconnected' || state === 'exited' ? [] : [{ path, name }];
413+
}
389414

415+
// Multiple sessions are present
390416
const activeSessions = (
391417
await Promise.all(
392-
allSessions.map(async session => {
418+
allSessionTabs.map(async session => {
393419
const isDisconnected = await session.locator('.codicon-positron-status-disconnected').isVisible();
394420
if (isDisconnected) { return null; }
395421

@@ -515,17 +541,25 @@ export class Sessions {
515541
const activeSessionsFromConsole = await this.getActiveSessions();
516542
expect(activeSessionsFromConsole).toHaveLength(count);
517543
} else {
518-
await expect(this.sessionTabs).toHaveCount(count);
544+
if (count === 0) {
545+
await expect(this.sessionTabs).not.toBeVisible();
546+
await expect(this.metadataButton).not.toBeVisible();
547+
} else if (count === 1) {
548+
await expect(this.sessionTabs).not.toBeVisible();
549+
await expect(this.metadataButton).toBeVisible();
550+
} else {
551+
await expect(this.sessionTabs).toHaveCount(count);
552+
}
519553
}
520-
}).toPass({ timeout: 5000 });
554+
}).toPass({ timeout: 45000 });
521555
});
522556
}
523557

524558
/**
525559
* Verify: the active sessions match between console and session picker
526560
* @param count the expected number of active sessions
527561
*/
528-
async expectSessionListsToMatch() {
562+
async expectSessionListsToMatch(numSessions?: number) {
529563
await test.step('Verify active sessions match between console and session picker', async () => {
530564
await expect(async () => {
531565
const activeSessionsFromConsole = await this.getActiveSessions();

test/e2e/tests/sessions/sessions.test.ts

+9-13
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,18 @@ test.describe('Sessions', {
4444

4545
// Start Python session
4646
pythonSession.id = await sessions.launch({ ...pythonSession, waitForReady: false });
47+
rSession.id = await sessions.launch({ ...rSession, waitForReady: false });
4748

48-
// Verify Python session is visible and transitions from active --> idle
49-
await sessions.expectStatusToBe(pythonSession.id, 'active');
49+
// Verify R session transitions from active --> idle while Python session remains idle
50+
await sessions.expectStatusToBe(rSession.id, 'active');
51+
await sessions.expectStatusToBe(rSession.id, 'idle');
5052
await sessions.expectStatusToBe(pythonSession.id, 'idle');
5153

52-
// Restart Python session and confirm state returns to active --> idle
54+
// Restart Python session, verify Python transitions to active --> idle and R remains idle
5355
await sessions.restart(pythonSession.id, false);
5456
await sessions.expectStatusToBe(pythonSession.id, 'active');
5557
await sessions.expectStatusToBe(pythonSession.id, 'idle');
56-
57-
// Start R session
58-
rSession.id = await sessions.launch({ ...rSession, waitForReady: false });
59-
60-
// Verify R session transitions from active --> idle while Python session remains idle
61-
await sessions.expectStatusToBe(rSession.id, 'active');
6258
await sessions.expectStatusToBe(rSession.id, 'idle');
63-
await sessions.expectStatusToBe(pythonSession.id, 'idle');
6459

6560
// Shutdown Python session, verify Python transitions to disconnected while R remains idle
6661
await sessions.select(pythonSession.id);
@@ -201,14 +196,15 @@ test.describe('Sessions', {
201196
await sessions.expectSessionListsToMatch();
202197

203198
// Restart Python session and verify active sessions
204-
await sessions.restart(pythonSession.name);
205-
await sessions.expectSessionCountToBe(1, 'active');
199+
await console.barClearButton.click();
200+
await sessions.restartButton.click();
206201
await sessions.expectSessionListsToMatch();
207202
});
208203

209204
test('Validate can delete sessions', async function ({ app }) {
210205
const sessions = app.workbench.sessions;
211206
const variables = app.workbench.variables;
207+
const console = app.workbench.console;
212208

213209
// Ensure sessions exist and are idle
214210
await sessions.reuseSessionIfExists(pythonSession);
@@ -221,7 +217,7 @@ test.describe('Sessions', {
221217
await variables.expectRuntimeToBe(rSession.name);
222218

223219
// Delete 2nd session and verify no active sessions or runtime in session picker
224-
await sessions.delete(rSession.name);
220+
await console.barTrashButton.click();
225221
await expect(sessions.startSessionButton).toHaveText('Start Session');
226222
await sessions.expectSessionCountToBe(0);
227223
await sessions.expectSessionListsToMatch();

test/e2e/tests/top-action-bar/session-button.test.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6+
import { expect } from '@playwright/test';
67
import { SessionInfo } from '../../infra';
78
import { test, tags } from '../_test.setup';
89

@@ -30,14 +31,20 @@ test.describe('Top Action Bar: Session Button', {
3031
});
3132

3233
test('Python - Verify session starts and displays as running', async function ({ app }) {
33-
pythonSession.id = await app.workbench.sessions.launch({ ...pythonSession, triggerMode: 'session-picker' });
34-
await app.workbench.sessions.expectSessionPickerToBe(pythonSession);
35-
await app.workbench.sessions.expectStatusToBe(pythonSession.id, 'idle');
34+
const sessions = app.workbench.sessions;
35+
36+
pythonSession.id = await sessions.launch({ ...pythonSession, triggerMode: 'session-picker' });
37+
await sessions.expectSessionPickerToBe(pythonSession);
38+
const { state } = await sessions.getMetadata();
39+
expect(state).toBe('idle');
3640
});
3741

3842
test('R - Verify session starts and displays as running', async function ({ app }) {
39-
rSession.id = await app.workbench.sessions.launch({ ...rSession, triggerMode: 'session-picker' });
40-
await app.workbench.sessions.expectSessionPickerToBe(rSession);
41-
await app.workbench.sessions.expectStatusToBe(rSession.id, 'idle');
43+
const sessions = app.workbench.sessions;
44+
45+
rSession.id = await sessions.launch({ ...rSession, triggerMode: 'session-picker' });
46+
await sessions.expectSessionPickerToBe(rSession);
47+
const { state } = await sessions.getMetadata();
48+
expect(state).toBe('idle');
4249
});
4350
});

0 commit comments

Comments
 (0)