2022-03-03 19:32:43 +01:00
|
|
|
import * as cp from "child_process"
|
2022-02-22 19:43:13 +01:00
|
|
|
import { promises as fs } from "fs"
|
2022-03-03 19:32:43 +01:00
|
|
|
import * as os from "os"
|
2022-02-22 19:43:13 +01:00
|
|
|
import * as path from "path"
|
2022-03-03 19:32:43 +01:00
|
|
|
import * as util from "util"
|
2021-06-22 23:34:44 +02:00
|
|
|
import { describe, test, expect } from "./baseFixture"
|
2022-03-03 19:32:43 +01:00
|
|
|
import { CodeServer } from "./models/CodeServer"
|
|
|
|
|
|
|
|
describe("code-server", true, [], {}, () => {
|
|
|
|
// TODO@asher: Generalize this? Could be nice if we were to ever need
|
|
|
|
// multiple migration tests in other suites.
|
|
|
|
const instances = new Map<string, CodeServer>()
|
|
|
|
test.afterAll(async () => {
|
|
|
|
const procs = Array.from(instances.values())
|
|
|
|
instances.clear()
|
|
|
|
await Promise.all(procs.map((cs) => cs.close()))
|
|
|
|
})
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Spawn a specific version of code-server using the install script.
|
|
|
|
*/
|
|
|
|
const spawn = async (version: string, dir?: string): Promise<CodeServer> => {
|
|
|
|
let instance = instances.get(version)
|
|
|
|
if (!instance) {
|
|
|
|
await util.promisify(cp.exec)(`./install.sh --method standalone --version ${version}`, {
|
|
|
|
cwd: path.join(__dirname, "../.."),
|
|
|
|
})
|
|
|
|
|
|
|
|
instance = new CodeServer(
|
|
|
|
"code-server@" + version,
|
|
|
|
["--auth=none"],
|
|
|
|
{ VSCODE_DEV: "" },
|
|
|
|
dir,
|
|
|
|
`${os.homedir()}/.local/lib/code-server-${version}`,
|
|
|
|
)
|
|
|
|
|
|
|
|
instances.set(version, instance)
|
|
|
|
}
|
|
|
|
|
|
|
|
return instance
|
|
|
|
}
|
2021-04-20 00:25:57 +02:00
|
|
|
|
2021-06-22 23:34:44 +02:00
|
|
|
test("should navigate to home page", async ({ codeServerPage }) => {
|
2021-04-20 21:41:54 +02:00
|
|
|
// We navigate codeServer before each test
|
|
|
|
// and we start the test with a storage state
|
|
|
|
// which means we should be logged in
|
|
|
|
// so it should be on the address
|
2021-06-10 15:09:38 +02:00
|
|
|
const url = codeServerPage.page.url()
|
2021-04-20 21:41:54 +02:00
|
|
|
// We use match because there may be a / at the end
|
|
|
|
// so we don't want it to fail if we expect http://localhost:8080 to match http://localhost:8080/
|
2021-06-22 23:34:44 +02:00
|
|
|
expect(url).toMatch(await codeServerPage.address())
|
2021-04-20 21:41:54 +02:00
|
|
|
})
|
2021-04-20 00:25:57 +02:00
|
|
|
|
2021-06-10 15:09:38 +02:00
|
|
|
test("should always see the code-server editor", async ({ codeServerPage }) => {
|
|
|
|
expect(await codeServerPage.isEditorVisible()).toBe(true)
|
2021-04-20 00:25:57 +02:00
|
|
|
})
|
|
|
|
|
2021-06-10 15:09:38 +02:00
|
|
|
test("should always have a connection", async ({ codeServerPage }) => {
|
|
|
|
expect(await codeServerPage.isConnected()).toBe(true)
|
2021-04-30 21:33:20 +02:00
|
|
|
})
|
|
|
|
|
2021-06-10 15:09:38 +02:00
|
|
|
test("should show the Integrated Terminal", async ({ codeServerPage }) => {
|
|
|
|
await codeServerPage.focusTerminal()
|
|
|
|
expect(await codeServerPage.page.isVisible("#terminal")).toBe(true)
|
2021-04-20 00:25:57 +02:00
|
|
|
})
|
2022-02-22 19:43:13 +01:00
|
|
|
|
|
|
|
test("should open a file", async ({ codeServerPage }) => {
|
|
|
|
const dir = await codeServerPage.workspaceDir
|
|
|
|
const file = path.join(dir, "foo")
|
|
|
|
await fs.writeFile(file, "bar")
|
|
|
|
await codeServerPage.openFile(file)
|
|
|
|
})
|
|
|
|
|
2022-03-03 19:32:43 +01:00
|
|
|
test("should migrate state to avoid collisions", async ({ codeServerPage }) => {
|
|
|
|
// This can take a very long time in development because of how long pages
|
|
|
|
// take to load and we are doing a lot of that here.
|
|
|
|
test.slow()
|
|
|
|
|
2022-02-22 19:43:13 +01:00
|
|
|
const dir = await codeServerPage.workspaceDir
|
2022-03-03 19:32:43 +01:00
|
|
|
const files = [path.join(dir, "foo"), path.join(dir, "bar")]
|
|
|
|
await Promise.all(
|
|
|
|
files.map((file) => {
|
|
|
|
return fs.writeFile(file, path.basename(file))
|
|
|
|
}),
|
|
|
|
)
|
2022-02-22 19:43:13 +01:00
|
|
|
|
2022-03-03 19:32:43 +01:00
|
|
|
// Open a file in the latest instance.
|
|
|
|
await codeServerPage.openFile(files[0])
|
|
|
|
await codeServerPage.stateFlush()
|
2022-02-22 19:43:13 +01:00
|
|
|
|
2022-03-03 19:32:43 +01:00
|
|
|
// Open a file in an older version of code-server. It should not see the
|
|
|
|
// file opened in the new instance since the database has a different
|
|
|
|
// name. This must be accessed through the proxy so it shares the same
|
|
|
|
// domain and can write to the same database.
|
|
|
|
const cs = await spawn("4.0.2", dir)
|
|
|
|
const address = new URL(await cs.address())
|
|
|
|
await codeServerPage.navigate("/proxy/" + address.port + "/")
|
|
|
|
await codeServerPage.openFile(files[1])
|
|
|
|
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
|
|
|
|
await codeServerPage.stateFlush()
|
2022-02-22 19:43:13 +01:00
|
|
|
|
2022-03-03 19:32:43 +01:00
|
|
|
// Move back to latest code-server. We should see the file we previously
|
|
|
|
// opened with it but not the old code-server file because the new instance
|
|
|
|
// already created its own database on this path and will avoid migrating.
|
|
|
|
await codeServerPage.navigate()
|
|
|
|
await codeServerPage.waitForTab(files[0])
|
|
|
|
expect(await codeServerPage.tabIsVisible(files[1])).toBe(false)
|
2022-02-22 19:43:13 +01:00
|
|
|
|
2022-03-03 19:32:43 +01:00
|
|
|
// Open a new path in latest code-server. This one should migrate the
|
|
|
|
// database from old code-server but see nothing from the new database
|
|
|
|
// created on the root.
|
|
|
|
await codeServerPage.navigate("/vscode")
|
|
|
|
await codeServerPage.waitForTab(files[1])
|
|
|
|
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
|
|
|
|
// Should still be open after a reload.
|
|
|
|
await codeServerPage.navigate("/vscode")
|
|
|
|
await codeServerPage.waitForTab(files[1])
|
|
|
|
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
|
2022-02-22 19:43:13 +01:00
|
|
|
})
|
2021-04-20 00:25:57 +02:00
|
|
|
})
|