Skip to content

Commit 9ea1863

Browse files
authored
Merge branch 'master' into upgrade-vscode-1.53
2 parents 5f3afbf + 63733c3 commit 9ea1863

File tree

19 files changed

+338
-18
lines changed

19 files changed

+338
-18
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
* @cdr/code-server-reviewers
2+
13
ci/helm-chart @Matthew-Beckett @alexgorbatchev

.github/workflows/ci.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ jobs:
2424
test:
2525
needs: linux-amd64
2626
runs-on: ubuntu-latest
27+
env:
28+
PASSWORD: e45432jklfdsab
29+
CODE_SERVER_ADDRESS: http://localhost:8080
2730
steps:
2831
- uses: actions/checkout@v1
2932
- name: Download release packages
@@ -37,9 +40,14 @@ jobs:
3740
- uses: microsoft/playwright-github-action@v1
3841
- name: Install dependencies and run tests
3942
run: |
40-
node ./release-packages/code-server*-linux-amd64 &
43+
./release-packages/code-server*-linux-amd64/bin/code-server --home $CODE_SERVER_ADDRESS/healthz &
4144
yarn --frozen-lockfile
4245
yarn test
46+
- name: Upload test artifacts
47+
uses: actions/upload-artifact@v2
48+
with:
49+
name: test-videos
50+
path: ./test/videos
4351

4452
release:
4553
runs-on: ubuntu-latest

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@ node-*
1515
/lib/coder-cloud-agent
1616
.home
1717
coverage
18-
**/.DS_Store
18+
**/.DS_Store
19+
test/videos
20+
test/screenshots

ci/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ Make sure you have `$GITHUB_TOKEN` set and [hub](https://github.com/github/hub)
4343
9. Update the AUR package.
4444
- Instructions on updating the AUR package are at [cdr/code-server-aur](https://github.com/cdr/code-server-aur).
4545
10. Wait for the npm package to be published.
46-
11. Update the homebrew package.
47-
- Send a pull request to [homebrew-core](https://github.com/Homebrew/homebrew-core) with the URL in the [formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/code-server.rb) updated.
46+
11. Update the [homebrew package](https://github.com/Homebrew/homebrew-core/blob/master/Formula/code-server.rb).
47+
1. Install [homebrew](https://brew.sh/)
48+
2. Run `brew bump-formula-pr --version=3.8.1 code-server` and update the version accordingly. This will bump the version and open a PR. Note: this will only work once the version is published on npm.
4849

4950
## Updating Code Coverage in README
5051

ci/dev/test.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ main() {
99
# information. We must also run it from the root otherwise coverage will not
1010
# include our source files.
1111
cd "$OLDPWD"
12+
if [[ -z ${PASSWORD-} ]] || [[ -z ${CODE_SERVER_ADDRESS-} ]]; then
13+
echo "The end-to-end testing suites rely on your local environment"
14+
echo -e "\n"
15+
echo "Please set the following environment variables locally:"
16+
echo " \$PASSWORD"
17+
echo " \$CODE_SERVER_ADDRESS"
18+
echo -e "\n"
19+
echo "Please make sure you have code-server running locally with the flag:"
20+
echo " --home \$CODE_SERVER_ADDRESS/healthz "
21+
echo -e "\n"
22+
exit 1
23+
fi
1224
CS_DISABLE_PLUGINS=true ./test/node_modules/.bin/jest "$@"
1325
}
1426

docs/CONTRIBUTING.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ There are several differences, however. You must:
3535
- Use Node.js version 12.x (or greater)
3636
- Have [yarn](https://classic.yarnpkg.com/en/) installed (which is used to install JS packages and run development scripts)
3737
- Have [nfpm](https://github.com/goreleaser/nfpm) (which is used to build `.deb` and `.rpm` packages and [jq](https://stedolan.github.io/jq/) (used to build code-server releases) installed
38+
- Have [shfmt](https://pkg.go.dev/mvdan.cc/sh/v3) installed to run `yarn fmt` (requires Go is installed on your system)
3839

39-
The [CI container](../ci/images/debian8/Dockerfile) is a useful reference for all
40+
The [CI container](../ci/images/debian10/Dockerfile) is a useful reference for all
4041
of the dependencies code-server uses.
4142

4243
## Development Workflow
@@ -120,10 +121,10 @@ node ./release
120121

121122
The `code-server` script serves an HTTP API for login and starting a remote VS Code process.
122123

123-
The CLI code is in [./src/node](./src/node) and the HTTP routes are implemented in
124-
[./src/node/app](./src/node/app).
124+
The CLI code is in [src/node](../src/node) and the HTTP routes are implemented in
125+
[src/node/routes](../src/node/routes).
125126

126-
Most of the meaty parts are in the VS Code portion of the codebase under [./lib/vscode](./lib/vscode), which we described next.
127+
Most of the meaty parts are in the VS Code portion of the codebase under [lib/vscode](../lib/vscode), which we described next.
127128

128129
### Modifications to VS Code
129130

@@ -133,7 +134,7 @@ and exposed an API to the front-end for file access and all UI needs.
133134

134135
Over time, Microsoft added support to VS Code to run it on the web. They have made
135136
the front-end open source, but not the server. As such, code-server v2 (and later) uses
136-
the VS Code front-end and implements the server. We do this by using a git subtree to fork and modify VS Code. This code lives under [./lib/vscode](./lib/vscode).
137+
the VS Code front-end and implements the server. We do this by using a git subtree to fork and modify VS Code. This code lives under [lib/vscode](../lib/vscode).
137138

138139
Some noteworthy changes in our version of VS Code:
139140

docs/FAQ.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
- [Questions?](#questions)
66
- [iPad Status?](#ipad-status)
7-
- [Community projects (awesome-code-server)](#community-projects-awesome-code-server)
7+
- [Community Projects (awesome-code-server)](#community-projects-awesome-code-server)
88
- [How can I reuse my VS Code configuration?](#how-can-i-reuse-my-vs-code-configuration)
99
- [Differences compared to VS Code?](#differences-compared-to-vs-code)
1010
- [How can I request a missing extension?](#how-can-i-request-a-missing-extension)
@@ -43,7 +43,7 @@ Please file all questions and support requests at https://github.com/cdr/code-se
4343

4444
Please see [./ipad.md](./ipad.md).
4545

46-
## Community projects (awesome-code-server)
46+
## Community Projects (awesome-code-server)
4747

4848
Visit the [awesome-code-server](https://github.com/cdr/awesome-code-server) repository to view community projects and guides with code-server! Feel free to add your own!
4949

package.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,16 @@
143143
"lines": 40
144144
}
145145
},
146+
"testTimeout": 30000,
147+
"globalSetup": "<rootDir>/test/globalSetup.ts",
146148
"modulePathIgnorePatterns": [
147-
"<rootDir>/release"
149+
"<rootDir>/lib/vscode",
150+
"<rootDir>/release-packages",
151+
"<rootDir>/release",
152+
"<rootDir>/release-standalone",
153+
"<rootDir>/release-npm-package",
154+
"<rootDir>/release-gcp",
155+
"<rootDir>/release-images"
148156
]
149157
}
150158
}

src/browser/pages/login.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
body {
2+
min-height: 568px;
3+
min-width: 320px;
24
overflow: auto;
35
}
46

@@ -15,6 +17,12 @@ body {
1517
width: 100%;
1618
}
1719

20+
@media (max-width: 600px) {
21+
.login-form > .field {
22+
flex-direction: column;
23+
}
24+
}
25+
1826
.login-form > .error {
1927
color: red;
2028
margin-top: 16px;
@@ -38,6 +46,13 @@ body {
3846
margin-left: 20px;
3947
}
4048

49+
@media (max-width: 600px) {
50+
.login-form > .field > .submit {
51+
margin-left: 0px;
52+
margin-top: 16px;
53+
}
54+
}
55+
4156
input {
4257
-webkit-appearance: none;
4358
}

src/node/routes/login.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { rootPath } from "../constants"
77
import { authenticated, getCookieDomain, redirect, replaceTemplates } from "../http"
88
import { hash, humanPath } from "../util"
99

10-
enum Cookie {
10+
export enum Cookie {
1111
Key = "key",
1212
}
1313

test/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const CODE_SERVER_ADDRESS = process.env.CODE_SERVER_ADDRESS || "http://localhost:8080"
2+
export const PASSWORD = process.env.PASSWORD || "e45432jklfdsab"
3+
export const STORAGE = process.env.STORAGE || ""

test/e2e.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { chromium, Page, Browser } from "playwright"
2+
import { CODE_SERVER_ADDRESS } from "./constants"
23

34
let browser: Browser
45
let page: Page
@@ -17,7 +18,7 @@ afterEach(async () => {
1718
})
1819

1920
it("should see the login page", async () => {
20-
await page.goto("http://localhost:8080")
21+
await page.goto(CODE_SERVER_ADDRESS)
2122
// It should send us to the login page
2223
expect(await page.title()).toBe("code-server login")
2324
})

test/globalSetup.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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
4+
import { chromium } from "playwright"
5+
import { CODE_SERVER_ADDRESS, PASSWORD } from "./constants"
6+
import * as wtfnode from "./wtfnode"
7+
8+
module.exports = async () => {
9+
console.log("\n🚨 Running Global Setup for Jest Tests")
10+
console.log(" Please hang tight...")
11+
const browser = await chromium.launch()
12+
const context = await browser.newContext()
13+
const page = await context.newPage()
14+
15+
if (process.env.WTF_NODE) {
16+
wtfnode.setup()
17+
}
18+
19+
await page.goto(CODE_SERVER_ADDRESS, { waitUntil: "domcontentloaded" })
20+
// Type in password
21+
await page.fill(".password", PASSWORD)
22+
// Click the submit button and login
23+
await page.click(".submit")
24+
25+
// Save storage state and store as an env variable
26+
// More info: https://playwright.dev/docs/auth?_highlight=authe#reuse-authentication-state
27+
const storage = await context.storageState()
28+
process.env.STORAGE = JSON.stringify(storage)
29+
30+
await page.close()
31+
await browser.close()
32+
await context.close()
33+
console.log("✅ Global Setup for Jest Tests is now complete.")
34+
}

test/goHome.test.ts

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { chromium, Page, Browser, BrowserContext, Cookie } from "playwright"
2+
import { hash } from "../src/node/util"
3+
import { CODE_SERVER_ADDRESS, PASSWORD, STORAGE } from "./constants"
4+
import { createCookieIfDoesntExist } from "./helpers"
5+
6+
describe("go home", () => {
7+
let browser: Browser
8+
let page: Page
9+
let context: BrowserContext
10+
11+
beforeAll(async () => {
12+
browser = await chromium.launch()
13+
// Create a new context with the saved storage state
14+
const storageState = JSON.parse(STORAGE) || {}
15+
16+
const cookieToStore = {
17+
sameSite: "Lax" as const,
18+
name: "key",
19+
value: hash(PASSWORD),
20+
domain: "localhost",
21+
path: "/",
22+
expires: -1,
23+
httpOnly: false,
24+
secure: false,
25+
}
26+
27+
// For some odd reason, the login method used in globalSetup.ts doesn't always work
28+
// I don't know if it's on playwright clearing our cookies by accident
29+
// or if it's our cookies disappearing.
30+
// This means we need an additional check to make sure we're logged in.
31+
// We do this by manually adding the cookie to the browser environment
32+
// if it's not there at the time the test starts
33+
const cookies: Cookie[] = storageState.cookies || []
34+
// If the cookie exists in cookies then
35+
// this will return the cookies with no changes
36+
// otherwise if it doesn't exist, it will create it
37+
// hence the name maybeUpdatedCookies
38+
//
39+
// TODO(@jsjoeio)
40+
// The playwright storage thing sometimes works and sometimes doesn't. We should investigate this further
41+
// at some point.
42+
// See discussion: https://github.com/cdr/code-server/pull/2648#discussion_r575434946
43+
44+
const maybeUpdatedCookies = createCookieIfDoesntExist(cookies, cookieToStore)
45+
46+
context = await browser.newContext({
47+
storageState: { cookies: maybeUpdatedCookies },
48+
recordVideo: { dir: "./test/videos/" },
49+
})
50+
})
51+
52+
afterAll(async () => {
53+
// Remove password from local storage
54+
await context.clearCookies()
55+
56+
await context.close()
57+
await browser.close()
58+
})
59+
60+
beforeEach(async () => {
61+
page = await context.newPage()
62+
})
63+
64+
// NOTE: this test will fail if you do not run code-server with --home $CODE_SERVER_ADDRESS/healthz
65+
it("should see a 'Go Home' button in the Application Menu that goes to /healthz", async () => {
66+
const GO_HOME_URL = `${CODE_SERVER_ADDRESS}/healthz`
67+
// Sometimes a dialog shows up when you navigate
68+
// asking if you're sure you want to leave
69+
// so we listen if it comes, we accept it
70+
page.on("dialog", (dialog) => dialog.accept())
71+
72+
// waitUntil: "domcontentloaded"
73+
// In case the page takes a long time to load
74+
await page.goto(CODE_SERVER_ADDRESS, { waitUntil: "domcontentloaded" })
75+
76+
// Click the Home menu
77+
await page.click(".home-bar ul[aria-label='Home'] li")
78+
// See the Go Home button
79+
const goHomeButton = "a.action-menu-item span[aria-label='Go Home']"
80+
expect(await page.isVisible(goHomeButton))
81+
82+
// Click it and navigate to /healthz
83+
// NOTE: ran into issues of it failing intermittently
84+
// without having button: "middle"
85+
await Promise.all([page.waitForNavigation(), page.click(goHomeButton, { button: "middle" })])
86+
expect(page.url()).toBe(GO_HOME_URL)
87+
})
88+
})

test/helpers.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Borrowed from playwright
2+
export interface Cookie {
3+
name: string
4+
value: string
5+
domain: string
6+
path: string
7+
/**
8+
* Unix time in seconds.
9+
*/
10+
expires: number
11+
httpOnly: boolean
12+
secure: boolean
13+
sameSite: "Strict" | "Lax" | "None"
14+
}
15+
16+
/**
17+
* Checks if a cookie exists in array of cookies
18+
*/
19+
export function checkForCookie(cookies: Array<Cookie>, key: string): boolean {
20+
// Check for a cookie where the name is equal to key
21+
return Boolean(cookies.find((cookie) => cookie.name === key))
22+
}
23+
24+
/**
25+
* Creates a login cookie if one doesn't already exist
26+
*/
27+
export function createCookieIfDoesntExist(cookies: Array<Cookie>, cookieToStore: Cookie): Array<Cookie> {
28+
const cookieName = cookieToStore.name
29+
const doesCookieExist = checkForCookie(cookies, cookieName)
30+
if (!doesCookieExist) {
31+
const updatedCookies = [...cookies, cookieToStore]
32+
return updatedCookies
33+
}
34+
return cookies
35+
}

0 commit comments

Comments
 (0)