feat(e2e): add support running behind proxy (#5348)
* docs: update maintaining * chore(e2e): add maxFailures to playwright * fix(ci): skip submodule in e2e job We don't need the submodules for the e2e job. This will speed up the checkout step. * feat(ci): add test-e2e-proxy job This adds a new job to CI to run our tests behind Caddy and simulate code-server running against a reverse-proxy. * refactor: make e2e work with reverse proxy This refactors the e2e test in a couple ways: - remove setting cookie in localStorage (instead we pass --auth none) - refactor address() method to account for reverse proxy logic * Update test/e2e/models/CodeServer.ts * Update test/playwright.config.ts * Update test/utils/constants.ts Co-authored-by: Asher <ash@coder.com> * Update test/utils/helpers.ts Co-authored-by: Asher <ash@coder.com> Co-authored-by: Asher <ash@coder.com>
This commit is contained in:
@ -4,10 +4,10 @@ import { promises as fs } from "fs"
|
||||
import * as path from "path"
|
||||
import { Page } from "playwright"
|
||||
import * as util from "util"
|
||||
import { logError, plural } from "../../../src/common/util"
|
||||
import { logError, normalize, plural } from "../../../src/common/util"
|
||||
import { onLine } from "../../../src/node/util"
|
||||
import { PASSWORD, workspaceDir } from "../../utils/constants"
|
||||
import { idleTimer, tmpdir } from "../../utils/helpers"
|
||||
import { getMaybeProxiedCodeServer, idleTimer, tmpdir } from "../../utils/helpers"
|
||||
|
||||
interface CodeServerProcess {
|
||||
process: cp.ChildProcess
|
||||
@ -58,6 +58,7 @@ export class CodeServer {
|
||||
this.process = this.spawn()
|
||||
}
|
||||
const { address } = await this.process
|
||||
|
||||
return address
|
||||
}
|
||||
|
||||
@ -104,6 +105,8 @@ export class CodeServer {
|
||||
this.entry,
|
||||
"--extensions-dir",
|
||||
path.join(dir, "extensions"),
|
||||
"--auth",
|
||||
"none",
|
||||
...this.args,
|
||||
// Using port zero will spawn on a random port.
|
||||
"--bind-addr",
|
||||
@ -124,6 +127,10 @@ export class CodeServer {
|
||||
env: {
|
||||
...process.env,
|
||||
...this.env,
|
||||
// Set to empty string to prevent code-server from
|
||||
// using the existing instance when running the e2e tests
|
||||
// from an integrated terminal.
|
||||
VSCODE_IPC_HOOK_CLI: "",
|
||||
PASSWORD,
|
||||
},
|
||||
})
|
||||
@ -183,6 +190,13 @@ export class CodeServer {
|
||||
proc.kill()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not authentication is enabled.
|
||||
*/
|
||||
authEnabled(): boolean {
|
||||
return this.args.includes("password")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,11 +209,7 @@ export class CodeServer {
|
||||
export class CodeServerPage {
|
||||
private readonly editorSelector = "div.monaco-workbench"
|
||||
|
||||
constructor(
|
||||
private readonly codeServer: CodeServer,
|
||||
public readonly page: Page,
|
||||
private readonly authenticated: boolean,
|
||||
) {
|
||||
constructor(private readonly codeServer: CodeServer, public readonly page: Page) {
|
||||
this.page.on("console", (message) => {
|
||||
this.codeServer.logger.debug(message.text())
|
||||
})
|
||||
@ -224,12 +234,16 @@ export class CodeServerPage {
|
||||
* editor to become available.
|
||||
*/
|
||||
async navigate(endpoint = "/") {
|
||||
const to = new URL(endpoint, await this.codeServer.address())
|
||||
const address = await getMaybeProxiedCodeServer(this.codeServer)
|
||||
const noramlizedUrl = normalize(address + endpoint, true)
|
||||
const to = new URL(noramlizedUrl)
|
||||
|
||||
this.codeServer.logger.info(`navigating to ${to}`)
|
||||
await this.page.goto(to.toString(), { waitUntil: "networkidle" })
|
||||
|
||||
// Only reload editor if authenticated. Otherwise we'll get stuck
|
||||
// Only reload editor if auth is not enabled. Otherwise we'll get stuck
|
||||
// reloading the login page.
|
||||
if (this.authenticated) {
|
||||
if (!this.codeServer.authEnabled()) {
|
||||
await this.reloadUntilEditorIsReady()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user