Skip to content

Commit ba0364a

Browse files
committed
Run each e2e test in a new workspace
The workspaces also have settings to prevent the welcome page from appearing.
1 parent 4a47ce7 commit ba0364a

File tree

5 files changed

+52
-26
lines changed

5 files changed

+52
-26
lines changed

test/e2e/models/CodeServer.ts

+27-8
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1+
import { promises as fs } from "fs"
2+
import * as path from "path"
13
import { Page } from "playwright"
2-
import { CODE_SERVER_ADDRESS } from "../../utils/constants"
4+
import { CODE_SERVER_ADDRESS, workspaceDir } from "../../utils/constants"
5+
import { tmpdir } from "../../utils/helpers"
6+
37
// This is a Page Object Model
48
// We use these to simplify e2e test authoring
59
// See Playwright docs: https://playwright.dev/docs/pom/
610
export class CodeServer {
7-
page: Page
8-
editorSelector = "div.monaco-workbench"
11+
private readonly editorSelector = "div.monaco-workbench"
912

10-
constructor(page: Page) {
11-
this.page = page
12-
}
13+
constructor(public readonly page: Page) {}
1314

1415
/**
15-
* Navigates to CODE_SERVER_ADDRESS
16+
* Navigates to CODE_SERVER_ADDRESS. It will open a newly created random
17+
* directory.
1618
*/
1719
async navigate() {
18-
await this.page.goto(CODE_SERVER_ADDRESS, { waitUntil: "networkidle" })
20+
const dir = await this.createWorkspace()
21+
await this.page.goto(`${CODE_SERVER_ADDRESS}?folder=${dir}`, { waitUntil: "networkidle" })
1922
}
2023

2124
/**
@@ -113,4 +116,20 @@ export class CodeServer {
113116
await this.navigate()
114117
await this.reloadUntilEditorIsReady()
115118
}
119+
120+
/**
121+
* Create a random workspace and seed it with settings.
122+
*/
123+
private async createWorkspace(): Promise<string> {
124+
const dir = await tmpdir(workspaceDir)
125+
await fs.mkdir(path.join(dir, ".vscode"))
126+
await fs.writeFile(
127+
path.join(dir, ".vscode/settings.json"),
128+
JSON.stringify({
129+
"workbench.startupEditor": "none",
130+
}),
131+
"utf8",
132+
)
133+
return dir
134+
}
116135
}

test/playwright.config.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import path from "path"
66
const config: PlaywrightTestConfig = {
77
testDir: path.join(__dirname, "e2e"), // Search for tests in this directory.
88
timeout: 60000, // Each test is given 60 seconds.
9-
retries: 3, // Retry failing tests 2 times
9+
retries: process.env.CI ? 2 : 1, // Retry twice in CI due to flakiness.
1010
workers: 1,
1111
globalSetup: require.resolve("./utils/globalSetup.ts"),
1212
reporter: "list",
@@ -34,10 +34,4 @@ const config: PlaywrightTestConfig = {
3434
],
3535
}
3636

37-
if (process.env.CI) {
38-
// In CI, retry failing tests 2 times
39-
// in the event of flakiness
40-
config.retries = 2
41-
}
42-
4337
export default config

test/utils/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export const CODE_SERVER_ADDRESS = process.env.CODE_SERVER_ADDRESS || "http://localhost:8080"
22
export const PASSWORD = process.env.PASSWORD || "e45432jklfdsab"
33
export const storageState = JSON.parse(process.env.STORAGE || "{}")
4+
export const workspaceDir = "workspaces"

test/utils/globalSetup.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
// This setup runs before our e2e tests
2-
// so that it authenticates us into code-server
3-
// ensuring that we're logged in before we run any tests
41
import { chromium } from "playwright"
52
import { hash } from "../../src/node/util"
6-
import { PASSWORD } from "./constants"
3+
import { PASSWORD, workspaceDir } from "./constants"
4+
import { clean } from "./helpers"
75
import * as wtfnode from "./wtfnode"
86

7+
/**
8+
* Perform workspace cleanup and authenticate. This should be set up to run
9+
* before our tests execute.
10+
*/
911
export default async function () {
1012
console.log("\n🚨 Running Global Setup for Playwright End-to-End Tests")
1113
console.log(" Please hang tight...")
1214

15+
// Cleanup workspaces from previous tests.
16+
await clean(workspaceDir)
17+
1318
const cookieToStore = {
1419
sameSite: "Lax" as const,
1520
name: "key",

test/utils/helpers.ts

+14-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as fs from "fs"
1+
import { promises as fs } from "fs"
22
import * as os from "os"
33
import * as path from "path"
44

@@ -20,13 +20,20 @@ export function createLoggerMock() {
2020
}
2121

2222
/**
23-
* Create a uniquely named temporary directory.
24-
*
25-
* These directories are placed under a single temporary code-server directory.
23+
* Clean up directories left by a test. It is recommended to do this when a test
24+
* starts to avoid potentially accumulating infinite test directories.
25+
*/
26+
export async function clean(testName: string): Promise<void> {
27+
const dir = path.join(os.tmpdir(), `code-server/tests/${testName}`)
28+
await fs.rm(dir, { recursive: true })
29+
}
30+
31+
/**
32+
* Create a uniquely named temporary directory for a test.
2633
*/
2734
export async function tmpdir(testName: string): Promise<string> {
28-
const dir = path.join(os.tmpdir(), "code-server/tests")
29-
await fs.promises.mkdir(dir, { recursive: true })
35+
const dir = path.join(os.tmpdir(), `code-server/tests/${testName}`)
36+
await fs.mkdir(dir, { recursive: true })
3037

31-
return await fs.promises.mkdtemp(path.join(dir, `${testName}-`), { encoding: "utf8" })
38+
return await fs.mkdtemp(path.join(dir, `${testName}-`), { encoding: "utf8" })
3239
}

0 commit comments

Comments
 (0)