Skip to content

Commit 090687d

Browse files
committed
feat: add e2e test for logout
1 parent 5cec620 commit 090687d

File tree

4 files changed

+68
-8
lines changed

4 files changed

+68
-8
lines changed
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export enum Cookie {
2-
Key = "key",
3-
}
2+
Key = 'key',
3+
}

lib/vscode/src/vs/workbench/browser/parts/titlebar/menubarControl.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import { registerThemingParticipant, IThemeService } from 'vs/platform/theme/com
99
import { MenuBarVisibility, getTitleBarStyle, IWindowOpenable, getMenuBarVisibility } from 'vs/platform/windows/common/windows';
1010
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
1111
import { IAction, Action, SubmenuAction, Separator } from 'vs/base/common/actions';
12-
import * as DOM from 'vs/base/browser/dom';
13-
import { addDisposableListener, Dimension, EventType } from 'vs/base/browser/dom';
12+
import { addDisposableListener, Dimension, EventType, getCookieValue } from 'vs/base/browser/dom';
1413
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
1514
import { isMacintosh, isWeb, isIOS, isNative } from 'vs/base/common/platform';
1615
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
@@ -717,8 +716,8 @@ export class CustomMenubarControl extends MenubarControl {
717716

718717
webNavigationActions.push(new Action('logout', localize('logout', "Log out"), undefined, true,
719718
async (event?: MouseEvent) => {
720-
const COOKIE_KEY = 'key';
721-
const loginCookie = DOM.getCookieValue(COOKIE_KEY);
719+
const COOKIE_KEY = Cookie.Key;
720+
const loginCookie = getCookieValue(COOKIE_KEY);
722721

723722
this.logService.info('Logging out of code-server');
724723

@@ -735,7 +734,7 @@ export class CustomMenubarControl extends MenubarControl {
735734
} else {
736735
this.logService.warn('Could not log out because we could not find cookie');
737736
}
738-
}))
737+
}));
739738

740739
return webNavigationActions;
741740
}

src/node/routes/login.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ import { promises as fs } from "fs"
33
import { RateLimiter as Limiter } from "limiter"
44
import * as path from "path"
55
import safeCompare from "safe-compare"
6-
import { Cookie } from "../../../lib/vscode/src/vs/server/common/cookie"
76
import { rootPath } from "../constants"
87
import { authenticated, getCookieDomain, redirect, replaceTemplates } from "../http"
98
import { hash, humanPath } from "../util"
109

10+
export enum Cookie {
11+
Key = "key",
12+
}
13+
1114
// RateLimiter wraps around the limiter library for logins.
1215
// It allows 2 logins every minute and 12 logins every hour.
1316
class RateLimiter {

test/e2e/logout.test.ts

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { chromium, Page, Browser, BrowserContext } from "playwright"
2+
import { CODE_SERVER_ADDRESS, PASSWORD, E2E_VIDEO_DIR } from "../utils/constants"
3+
4+
describe("logout", () => {
5+
let browser: Browser
6+
let page: Page
7+
let context: BrowserContext
8+
9+
beforeAll(async () => {
10+
browser = await chromium.launch()
11+
context = await browser.newContext({
12+
recordVideo: { dir: E2E_VIDEO_DIR },
13+
})
14+
})
15+
16+
afterAll(async () => {
17+
await browser.close()
18+
})
19+
20+
beforeEach(async () => {
21+
page = await context.newPage()
22+
})
23+
24+
afterEach(async () => {
25+
await page.close()
26+
// Remove password from local storage
27+
await context.clearCookies()
28+
})
29+
30+
it("should be able login and logout", async () => {
31+
await page.goto(CODE_SERVER_ADDRESS)
32+
// Type in password
33+
await page.fill(".password", PASSWORD)
34+
// Click the submit button and login
35+
await page.click(".submit")
36+
// See the editor
37+
const codeServerEditor = await page.isVisible(".monaco-workbench")
38+
expect(codeServerEditor).toBeTruthy()
39+
40+
// Click the Application menu
41+
await page.click("[aria-label='Application Menu']")
42+
43+
// See the Log out button
44+
const logoutButton = "a.action-menu-item span[aria-label='Log out']"
45+
expect(await page.isVisible(logoutButton))
46+
47+
await page.hover(logoutButton)
48+
49+
await page.click(logoutButton)
50+
// it takes a second to navigate
51+
// and since page.url comes back immediately
52+
// we need this waitForNavigation, otherwise it will check
53+
// before navigation has finished and fail
54+
await page.waitForNavigation({ url: `${CODE_SERVER_ADDRESS}/login` })
55+
const currentUrl = page.url()
56+
expect(currentUrl).toBe(`${CODE_SERVER_ADDRESS}/login`)
57+
})
58+
})

0 commit comments

Comments
 (0)