Skip to content

refactor: move vscode tests to e2e #5911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Dec 21, 2022
56 changes: 43 additions & 13 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,49 @@ jobs:
if: steps.changed-files.outputs.any_changed == 'true'
run: yarn lint:ts

test-unit:
name: Run unit tests
runs-on: ubuntu-20.04
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 2

- name: Get changed files
id: changed-files
uses: tj-actions/[email protected]
with:
files: |
**/*.ts
files_ignore: |
lib/vscode/**

- name: Install Node.js v16
if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/setup-node@v3
with:
node-version: "16"

- name: Fetch dependencies from cache
if: steps.changed-files.outputs.any_changed == 'true'
id: cache-node-modules
uses: actions/cache@v3
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-build-

- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true' && steps.cache-node-modules.outputs.cache-hit != 'true'
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile

- name: Run unit tests
if: steps.changed-files.outputs.any_changed == 'true'
run: yarn test:unit

build:
name: Build code-server
runs-on: ubuntu-20.04
Expand Down Expand Up @@ -206,19 +249,6 @@ jobs:
if: steps.cache-vscode.outputs.cache-hit != 'true'
run: yarn build:vscode

# Our code imports code from VS Code's `out` directory meaning VS Code
# must be built before running these tests.
# TODO: Move to its own step?
- name: Run code-server unit tests
run: yarn test:unit
if: success()

- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
if: success()

# The release package does not contain any native modules
# and is neutral to architecture/os/libc version.
- name: Create release package
Expand Down
16 changes: 0 additions & 16 deletions ci/dev/test-unit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,6 @@ main() {
make -s out/index.js
popd

# Our code imports from `out` in order to work during development but if you
# have only built for production you will have not have this directory. In
# that case symlink `out` to a production build directory.
if [[ ! -e lib/vscode/out ]]; then
pushd lib
local out=(vscode-reh-web-*)
if [[ -d "${out[0]}" ]]; then
ln -s "../${out[0]}/out" ./vscode/out
else
echo "Could not find lib/vscode/out or lib/vscode-reh-web-*"
echo "Code must be built before running unit tests"
exit 1
fi
popd
fi

# We must keep jest in a sub-directory. See ../../test/package.json for more
# information. We must also run it from the root otherwise coverage will not
# include our source files.
Expand Down
6 changes: 3 additions & 3 deletions test/e2e/models/CodeServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export class CodeServer {
private async spawn(): Promise<CodeServerProcess> {
// This will be used both as the workspace and data directory to ensure
// instances don't bleed into each other.
const dir = await this.createWorkspace()
let dir = await this.createWorkspace()

return new Promise((resolve, reject) => {
const args = [
Expand All @@ -128,6 +128,8 @@ export class CodeServer {
path.join(dir, "extensions"),
"--auth",
"none",
// The last argument is the workspace to open.
...(this.args.includes("--ignore-last-opened") ? [] : [dir]),
...this.args,
// Using port zero will spawn on a random port.
"--bind-addr",
Expand All @@ -139,8 +141,6 @@ export class CodeServer {
path.join(dir, "config.yaml"),
"--user-data-dir",
dir,
// The last argument is the workspace to open.
dir,
]
this.logger.debug("spawning `node " + args.join(" ") + "`")
const proc = cp.spawn("node", args, {
Expand Down
128 changes: 128 additions & 0 deletions test/e2e/routes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { describe, test, expect } from "./baseFixture"
import { clean, tmpdir } from "../utils/helpers"
import * as path from "path"
import { promises as fs } from "fs"

const routes = ["/", "/vscode", "/vscode/"]

describe("VS Code Routes", ["--disable-workspace-trust"], {}, async () => {
const testName = "integrated-terminal"
test.beforeAll(async () => {
await clean(testName)
})

test("should load all route variations", async ({ codeServerPage }) => {
for (const route of routes) {
await codeServerPage.navigate(route)

// Check there were no redirections
const url = new URL(codeServerPage.page.url())
expect(url.pathname).toBe(route)

// Check that page loaded from correct route
const html = await codeServerPage.page.innerHTML("html")
switch (route) {
case "/":
case "/vscode/":
expect(html).toMatch(/src="\.\/[a-z]+-[0-9a-z]+\/static\//)
break
case "/vscode":
expect(html).toMatch(/src="\.\/vscode\/[a-z]+-[0-9a-z]+\/static\//)
break
}
}
})

test("should redirect to the passed in workspace using human-readable query", async ({ codeServerPage }) => {
const workspace = path.join(await tmpdir(testName), "test.code-workspace")
await fs.writeFile(workspace, "")

const url = new URL(codeServerPage.page.url())
expect(url.pathname).toBe("/")
expect(url.search).toBe(`?workspace=${workspace}`)
})
})

const CODE_WORKSPACE_DIR = process.env.CODE_WORKSPACE_DIR || ""
describe("VS Code Routes with code-workspace", ["--disable-workspace-trust", CODE_WORKSPACE_DIR], {}, async () => {
const testName = "vscode-routes"
test.beforeAll(async () => {
await clean(testName)
})

test("should redirect to the passed in workspace using human-readable query", async ({ codeServerPage }) => {
const url = new URL(codeServerPage.page.url())
expect(url.pathname).toBe("/")
expect(url.search).toBe(`?workspace=${CODE_WORKSPACE_DIR}`)
})
})

const CODE_FOLDER_DIR = process.env.CODE_FOLDER_DIR || ""
describe("VS Code Routes with code-workspace", ["--disable-workspace-trust", CODE_FOLDER_DIR], {}, async () => {
const testName = "vscode-routes"
test.beforeAll(async () => {
await clean(testName)
})

test("should redirect to the passed in folder using human-readable query", async ({ codeServerPage }) => {
const url = new URL(codeServerPage.page.url())
expect(url.pathname).toBe("/")
expect(url.search).toBe(`?folder=${CODE_FOLDER_DIR}`)
})
})

describe(
"VS Code Routes with ignore-last-opened",
["--disable-workspace-trust", "--ignore-last-opened"],
{},
async () => {
test("should not redirect", async ({ codeServerPage }) => {
await codeServerPage.navigate(`/`)
// No redirections.
const url = new URL(codeServerPage.page.url())
expect(url.pathname).toBe("/")
expect(url.search).toBe("")
})
},
)

describe(
"VS Code Routes with no workspace or folder",
["--disable-workspace-trust"],
{},
async () => {
test("should redirect to last query folder/workspace", async ({ codeServerPage }) => {
const folder = process.env.CODE_FOLDER_DIR
const workspace = process.env.CODE_WORKSPACE_DIR
await codeServerPage.navigate(`/?folder=${folder}&workspace=${workspace}`)

// If you visit again without query parameters it will re-attach them by
// redirecting. It should always redirect to the same route.
for (const route of routes) {
await codeServerPage.navigate(route)
const url = new URL(codeServerPage.page.url())
expect(url.pathname).toBe(route)
expect(url.search).toBe(`?folder=${folder}&workspace=${workspace}`)
}
})
},
)

describe(
"VS Code Routes with no workspace or folder",
["--disable-workspace-trust"],
{},
async () => {
test("should not redirect if ew passed in", async ({ codeServerPage }) => {
const folder = process.env.CODE_FOLDER_DIR
const workspace = process.env.CODE_WORKSPACE_DIR
await codeServerPage.navigate(`/?folder=${folder}&workspace=${workspace}`)

// Closing the folder should stop the redirecting.
await codeServerPage.navigate("/?ew=true")
let url = new URL(codeServerPage.page.url())
expect(url.pathname).toBe("/")
expect(url.search).toBe("?ew=true")
})
},
)
137 changes: 0 additions & 137 deletions test/unit/node/routes/vscode.test.ts

This file was deleted.

Loading