From ed839c9a03b392880da84823d9f133ded7031b25 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 9 Mar 2021 15:14:38 -0700 Subject: [PATCH 01/10] feat: add test:e2e and test:unit to package.json --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index 10aadeb2..6c3eebdf 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,9 @@ "release:standalone": "./ci/build/build-standalone-release.sh", "release:github-draft": "./ci/build/release-github-draft.sh", "release:github-assets": "./ci/build/release-github-assets.sh", + "test:e2e": "./ci/dev/test.sh", "test:standalone-release": "./ci/build/test-standalone-release.sh", + "test:unit": "./ci/dev/test.sh", "package": "./ci/build/build-packages.sh", "postinstall": "./ci/dev/postinstall.sh", "update:vscode": "./ci/dev/update-vscode.sh", From 3f7104bb4ee06f27e42b74967e928b873fb9c956 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 9 Mar 2021 16:32:31 -0700 Subject: [PATCH 02/10] refactor: move unit tests to test/unit --- test/{ => unit}/cli.test.ts | 4 +- test/{ => unit}/constants.test.ts | 6 +-- test/{ => unit}/emitter.test.ts | 4 +- test/{ => unit}/health.test.ts | 4 +- test/{ => unit}/http.test.ts | 2 +- test/{ => unit}/plugin.test.ts | 10 ++-- test/{ => unit}/proxy.test.ts | 4 +- test/{ => unit}/register.test.ts | 8 +-- test/{ => unit}/serviceWorker.test.ts | 8 +-- test/{ => unit}/socket.test.ts | 6 +-- test/unit/test-plugin/.eslintrc.yaml | 5 ++ test/unit/test-plugin/.gitignore | 1 + test/unit/test-plugin/Makefile | 6 +++ test/unit/test-plugin/package.json | 16 ++++++ test/unit/test-plugin/public/icon.svg | 1 + test/unit/test-plugin/public/index.html | 10 ++++ test/unit/test-plugin/src/index.ts | 52 ++++++++++++++++++ test/unit/test-plugin/tsconfig.json | 71 +++++++++++++++++++++++++ test/unit/test-plugin/yarn.lock | 70 ++++++++++++++++++++++++ test/{ => unit}/update.test.ts | 6 +-- test/{ => unit}/util.test.ts | 12 ++--- test/wtfnode.ts | 35 ------------ 22 files changed, 269 insertions(+), 72 deletions(-) rename test/{ => unit}/cli.test.ts (99%) rename test/{ => unit}/constants.test.ts (90%) rename test/{ => unit}/emitter.test.ts (95%) rename test/{ => unit}/health.test.ts (91%) rename test/{ => unit}/http.test.ts (94%) rename test/{ => unit}/plugin.test.ts (92%) rename test/{ => unit}/proxy.test.ts (96%) rename test/{ => unit}/register.test.ts (93%) rename test/{ => unit}/serviceWorker.test.ts (91%) rename test/{ => unit}/socket.test.ts (96%) create mode 100644 test/unit/test-plugin/.eslintrc.yaml create mode 100644 test/unit/test-plugin/.gitignore create mode 100644 test/unit/test-plugin/Makefile create mode 100644 test/unit/test-plugin/package.json create mode 100644 test/unit/test-plugin/public/icon.svg create mode 100644 test/unit/test-plugin/public/index.html create mode 100644 test/unit/test-plugin/src/index.ts create mode 100644 test/unit/test-plugin/tsconfig.json create mode 100644 test/unit/test-plugin/yarn.lock rename test/{ => unit}/update.test.ts (95%) rename test/{ => unit}/util.test.ts (96%) delete mode 100644 test/wtfnode.ts diff --git a/test/cli.test.ts b/test/unit/cli.test.ts similarity index 99% rename from test/cli.test.ts rename to test/unit/cli.test.ts index 6a0cfd7b..94c72205 100644 --- a/test/cli.test.ts +++ b/test/unit/cli.test.ts @@ -3,8 +3,8 @@ import * as fs from "fs-extra" import * as net from "net" import * as os from "os" import * as path from "path" -import { Args, parse, setDefaults, shouldOpenInExistingInstance } from "../src/node/cli" -import { paths, tmpdir } from "../src/node/util" +import { Args, parse, setDefaults, shouldOpenInExistingInstance } from "../../src/node/cli" +import { paths, tmpdir } from "../../src/node/util" type Mutable = { -readonly [P in keyof T]: T[P] diff --git a/test/constants.test.ts b/test/unit/constants.test.ts similarity index 90% rename from test/constants.test.ts rename to test/unit/constants.test.ts index 0cb33f2f..e4b14a6c 100644 --- a/test/constants.test.ts +++ b/test/unit/constants.test.ts @@ -1,8 +1,8 @@ -import { commit, getPackageJson, version } from "../src/node/constants" -import { loggerModule } from "./helpers" +import { commit, getPackageJson, version } from "../../src/node/constants" +import { loggerModule } from "../utils/helpers" // jest.mock is hoisted above the imports so we must use `require` here. -jest.mock("@coder/logger", () => require("./helpers").loggerModule) +jest.mock("@coder/logger", () => require("../utils/helpers").loggerModule) describe("constants", () => { describe("getPackageJson", () => { diff --git a/test/emitter.test.ts b/test/unit/emitter.test.ts similarity index 95% rename from test/emitter.test.ts rename to test/unit/emitter.test.ts index 3ea72ae2..ebc6491b 100644 --- a/test/emitter.test.ts +++ b/test/unit/emitter.test.ts @@ -1,8 +1,8 @@ // Note: we need to import logger from the root // because this is the logger used in logError in ../src/common/util -import { logger } from "../node_modules/@coder/logger" +import { logger } from "../../node_modules/@coder/logger" -import { Emitter } from "../src/common/emitter" +import { Emitter } from "../../src/common/emitter" describe("emitter", () => { let spy: jest.SpyInstance diff --git a/test/health.test.ts b/test/unit/health.test.ts similarity index 91% rename from test/health.test.ts rename to test/unit/health.test.ts index 4eae9c60..a8bdfb19 100644 --- a/test/health.test.ts +++ b/test/unit/health.test.ts @@ -1,5 +1,5 @@ -import * as httpserver from "./httpserver" -import * as integration from "./integration" +import * as httpserver from "../utils/httpserver" +import * as integration from "../utils/integration" describe("health", () => { let codeServer: httpserver.HttpServer | undefined diff --git a/test/http.test.ts b/test/unit/http.test.ts similarity index 94% rename from test/http.test.ts rename to test/unit/http.test.ts index 234fca0d..5275adc8 100644 --- a/test/http.test.ts +++ b/test/unit/http.test.ts @@ -1,4 +1,4 @@ -import { HttpCode, HttpError } from "../src/common/http" +import { HttpCode, HttpError } from "../../src/common/http" describe("http", () => { describe("HttpCode", () => { diff --git a/test/plugin.test.ts b/test/unit/plugin.test.ts similarity index 92% rename from test/plugin.test.ts rename to test/unit/plugin.test.ts index 24326ded..7df360df 100644 --- a/test/plugin.test.ts +++ b/test/unit/plugin.test.ts @@ -2,11 +2,11 @@ import { logger } from "@coder/logger" import * as express from "express" import * as fs from "fs" import * as path from "path" -import { HttpCode } from "../src/common/http" -import { AuthType } from "../src/node/cli" -import { codeServer, PluginAPI } from "../src/node/plugin" -import * as apps from "../src/node/routes/apps" -import * as httpserver from "./httpserver" +import { HttpCode } from "../../src/common/http" +import { AuthType } from "../../src/node/cli" +import { codeServer, PluginAPI } from "../../src/node/plugin" +import * as apps from "../../src/node/routes/apps" +import * as httpserver from "../utils/httpserver" const fsp = fs.promises // Jest overrides `require` so our usual override doesn't work. diff --git a/test/proxy.test.ts b/test/unit/proxy.test.ts similarity index 96% rename from test/proxy.test.ts rename to test/unit/proxy.test.ts index 84a2c35b..c5969ebf 100644 --- a/test/proxy.test.ts +++ b/test/unit/proxy.test.ts @@ -1,7 +1,7 @@ import bodyParser from "body-parser" import * as express from "express" -import * as httpserver from "./httpserver" -import * as integration from "./integration" +import * as httpserver from "../utils/httpserver" +import * as integration from "../utils/integration" describe("proxy", () => { const nhooyrDevServer = new httpserver.HttpServer() diff --git a/test/register.test.ts b/test/unit/register.test.ts similarity index 93% rename from test/register.test.ts rename to test/unit/register.test.ts index a80c2034..d19f6300 100644 --- a/test/register.test.ts +++ b/test/unit/register.test.ts @@ -1,5 +1,5 @@ import { JSDOM } from "jsdom" -import { loggerModule } from "./helpers" +import { loggerModule } from "../utils/helpers" describe("register", () => { describe("when navigator and serviceWorker are defined", () => { @@ -40,7 +40,7 @@ describe("register", () => { it("should register a ServiceWorker", () => { // Load service worker like you would in the browser - require("../src/browser/register") + require("../../src/browser/register") expect(mockRegisterFn).toHaveBeenCalled() expect(mockRegisterFn).toHaveBeenCalledTimes(1) }) @@ -54,7 +54,7 @@ describe("register", () => { }) // Load service worker like you would in the browser - require("../src/browser/register") + require("../../src/browser/register") expect(mockRegisterFn).toHaveBeenCalled() expect(loggerModule.logger.error).toHaveBeenCalled() @@ -78,7 +78,7 @@ describe("register", () => { it("should log an error to the console", () => { // Load service worker like you would in the browser - require("../src/browser/register") + require("../../src/browser/register") expect(spy).toHaveBeenCalled() expect(spy).toHaveBeenCalledTimes(1) expect(spy).toHaveBeenCalledWith("[Service Worker] navigator is undefined") diff --git a/test/serviceWorker.test.ts b/test/unit/serviceWorker.test.ts similarity index 91% rename from test/serviceWorker.test.ts rename to test/unit/serviceWorker.test.ts index 7933d1f4..c8b0a625 100644 --- a/test/serviceWorker.test.ts +++ b/test/unit/serviceWorker.test.ts @@ -58,7 +58,7 @@ describe("serviceWorker", () => { }) it("should add 3 listeners: install, activate and fetch", () => { - require("../src/browser/serviceWorker.ts") + require("../../src/browser/serviceWorker.ts") const listenerEventNames = listeners.map((listener) => listener.event) expect(listeners).toHaveLength(3) @@ -68,20 +68,20 @@ describe("serviceWorker", () => { }) it("should call the proper callbacks for 'install'", async () => { - require("../src/browser/serviceWorker.ts") + require("../../src/browser/serviceWorker.ts") emit("install") expect(spy).toHaveBeenCalledWith("[Service Worker] installed") expect(spy).toHaveBeenCalledTimes(1) }) it("should do nothing when 'fetch' is called", async () => { - require("../src/browser/serviceWorker.ts") + require("../../src/browser/serviceWorker.ts") emit("fetch") expect(spy).not.toHaveBeenCalled() }) it("should call the proper callbacks for 'activate'", async () => { - require("../src/browser/serviceWorker.ts") + require("../../src/browser/serviceWorker.ts") emit("activate") // Activate serviceWorker diff --git a/test/socket.test.ts b/test/unit/socket.test.ts similarity index 96% rename from test/socket.test.ts rename to test/unit/socket.test.ts index e614e94d..da0b404a 100644 --- a/test/socket.test.ts +++ b/test/unit/socket.test.ts @@ -3,9 +3,9 @@ import * as fs from "fs-extra" import * as net from "net" import * as path from "path" import * as tls from "tls" -import { Emitter } from "../src/common/emitter" -import { SocketProxyProvider } from "../src/node/socket" -import { generateCertificate, tmpdir } from "../src/node/util" +import { Emitter } from "../../src/common/emitter" +import { SocketProxyProvider } from "../../src/node/socket" +import { generateCertificate, tmpdir } from "../../src/node/util" describe("SocketProxyProvider", () => { const provider = new SocketProxyProvider() diff --git a/test/unit/test-plugin/.eslintrc.yaml b/test/unit/test-plugin/.eslintrc.yaml new file mode 100644 index 00000000..67a20fa6 --- /dev/null +++ b/test/unit/test-plugin/.eslintrc.yaml @@ -0,0 +1,5 @@ +settings: + import/resolver: + alias: + map: + - [code-server, ./typings/pluginapi.d.ts] diff --git a/test/unit/test-plugin/.gitignore b/test/unit/test-plugin/.gitignore new file mode 100644 index 00000000..1fcb1529 --- /dev/null +++ b/test/unit/test-plugin/.gitignore @@ -0,0 +1 @@ +out diff --git a/test/unit/test-plugin/Makefile b/test/unit/test-plugin/Makefile new file mode 100644 index 00000000..d01aa80a --- /dev/null +++ b/test/unit/test-plugin/Makefile @@ -0,0 +1,6 @@ +out/index.js: src/index.ts + # Typescript always emits, even on errors. + yarn build || rm out/index.js + +node_modules: package.json yarn.lock + yarn diff --git a/test/unit/test-plugin/package.json b/test/unit/test-plugin/package.json new file mode 100644 index 00000000..2fe72378 --- /dev/null +++ b/test/unit/test-plugin/package.json @@ -0,0 +1,16 @@ +{ + "private": true, + "name": "test-plugin", + "version": "1.0.0", + "engines": { + "code-server": "^3.7.0" + }, + "main": "out/index.js", + "devDependencies": { + "@types/express": "^4.17.8", + "typescript": "^4.0.5" + }, + "scripts": { + "build": "tsc" + } +} diff --git a/test/unit/test-plugin/public/icon.svg b/test/unit/test-plugin/public/icon.svg new file mode 100644 index 00000000..25b9cf04 --- /dev/null +++ b/test/unit/test-plugin/public/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/unit/test-plugin/public/index.html b/test/unit/test-plugin/public/index.html new file mode 100644 index 00000000..3485f18e --- /dev/null +++ b/test/unit/test-plugin/public/index.html @@ -0,0 +1,10 @@ + + + + + Test Plugin + + +

Welcome to the test plugin!

+ + diff --git a/test/unit/test-plugin/src/index.ts b/test/unit/test-plugin/src/index.ts new file mode 100644 index 00000000..772b59d8 --- /dev/null +++ b/test/unit/test-plugin/src/index.ts @@ -0,0 +1,52 @@ +import * as cs from "code-server" +import * as fspath from "path" + +export const plugin: cs.Plugin = { + displayName: "Test Plugin", + routerPath: "/test-plugin", + homepageURL: "https://example.com", + description: "Plugin used in code-server tests.", + + init(config) { + config.logger.debug("test-plugin loaded!") + }, + + router() { + const r = cs.express.Router() + r.get("/test-app", (_, res) => { + res.sendFile(fspath.resolve(__dirname, "../public/index.html")) + }) + r.get("/goland/icon.svg", (_, res) => { + res.sendFile(fspath.resolve(__dirname, "../public/icon.svg")) + }) + r.get("/error", () => { + throw new cs.HttpError("error", cs.HttpCode.LargePayload) + }) + return r + }, + + wsRouter() { + const wr = cs.WsRouter() + wr.ws("/test-app", (req) => { + cs.wss.handleUpgrade(req, req.ws, req.head, (ws) => { + req.ws.resume() + ws.send("hello") + }) + }) + return wr + }, + + applications() { + return [ + { + name: "Test App", + version: "4.0.0", + iconPath: "/icon.svg", + path: "/test-app", + + description: "This app does XYZ.", + homepageURL: "https://example.com", + }, + ] + }, +} diff --git a/test/unit/test-plugin/tsconfig.json b/test/unit/test-plugin/tsconfig.json new file mode 100644 index 00000000..5afea81b --- /dev/null +++ b/test/unit/test-plugin/tsconfig.json @@ -0,0 +1,71 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "./out" /* Redirect output structure to the directory. */, + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + "baseUrl": "./" /* Base directory to resolve non-absolute module names. */, + "paths": { + "code-server": ["../../typings/pluginapi"] + } /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */, + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "skipLibCheck": true /* Skip type checking of declaration files. */, + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +} diff --git a/test/unit/test-plugin/yarn.lock b/test/unit/test-plugin/yarn.lock new file mode 100644 index 00000000..f295de1e --- /dev/null +++ b/test/unit/test-plugin/yarn.lock @@ -0,0 +1,70 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.33" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" + integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== + dependencies: + "@types/node" "*" + +"@types/express-serve-static-core@*": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.13.tgz#d9af025e925fc8b089be37423b8d1eac781be084" + integrity sha512-RgDi5a4nuzam073lRGKTUIaL3eF2+H7LJvJ8eUnCI0wA6SNjXc44DCmWNiTLs/AZ7QlsFWZiw/gTG3nSQGL0fA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@^4.17.8": + version "4.17.8" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.8.tgz#3df4293293317e61c60137d273a2e96cd8d5f27a" + integrity sha512-wLhcKh3PMlyA2cNAB9sjM1BntnhPMiM0JOBwPBqttjHev2428MLEB4AYVN+d8s2iyCVZac+o41Pflm/ZH5vLXQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/mime@*": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a" + integrity sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q== + +"@types/node@*": + version "14.14.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f" + integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw== + +"@types/qs@*": + version "6.9.5" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.5.tgz#434711bdd49eb5ee69d90c1d67c354a9a8ecb18b" + integrity sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/serve-static@*": + version "1.13.6" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.6.tgz#866b1b8dec41c36e28c7be40ac725b88be43c5c1" + integrity sha512-nuRJmv7jW7VmCVTn+IgYDkkbbDGyIINOeu/G0d74X3lm6E5KfMeQPJhxIt1ayQeQB3cSxvYs1RA/wipYoFB4EA== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +typescript@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389" + integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ== diff --git a/test/update.test.ts b/test/unit/update.test.ts similarity index 95% rename from test/update.test.ts rename to test/unit/update.test.ts index d275be4a..0f5d55a6 100644 --- a/test/update.test.ts +++ b/test/unit/update.test.ts @@ -1,9 +1,9 @@ import * as fs from "fs-extra" import * as http from "http" import * as path from "path" -import { SettingsProvider, UpdateSettings } from "../src/node/settings" -import { LatestResponse, UpdateProvider } from "../src/node/update" -import { tmpdir } from "../src/node/util" +import { SettingsProvider, UpdateSettings } from "../../src/node/settings" +import { LatestResponse, UpdateProvider } from "../../src/node/update" +import { tmpdir } from "../../src/node/util" describe.skip("update", () => { let version = "1.0.0" diff --git a/test/util.test.ts b/test/unit/util.test.ts similarity index 96% rename from test/util.test.ts rename to test/unit/util.test.ts index 2681d877..31eace76 100644 --- a/test/util.test.ts +++ b/test/unit/util.test.ts @@ -10,11 +10,11 @@ import { split, trimSlashes, normalize, -} from "../src/common/util" -import { Cookie as CookieEnum } from "../src/node/routes/login" -import { hash } from "../src/node/util" -import { PASSWORD } from "./constants" -import { checkForCookie, createCookieIfDoesntExist, loggerModule, Cookie } from "./helpers" +} from "../../src/common/util" +import { Cookie as CookieEnum } from "../../src/node/routes/login" +import { hash } from "../../src/node/util" +import { PASSWORD } from "../utils/constants" +import { checkForCookie, createCookieIfDoesntExist, loggerModule, Cookie } from "../utils/helpers" const dom = new JSDOM() global.document = dom.window.document @@ -22,7 +22,7 @@ global.document = dom.window.document type LocationLike = Pick // jest.mock is hoisted above the imports so we must use `require` here. -jest.mock("@coder/logger", () => require("./helpers").loggerModule) +jest.mock("@coder/logger", () => require("../utils/helpers").loggerModule) describe("util", () => { describe("normalize", () => { diff --git a/test/wtfnode.ts b/test/wtfnode.ts deleted file mode 100644 index 2d31a4e6..00000000 --- a/test/wtfnode.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as util from "util" -import * as wtfnode from "wtfnode" - -// Jest seems to hijack console.log in a way that makes the output difficult to -// read. So we'll write directly to process.stderr instead. -const write = (...args: [any, ...any]) => { - if (args.length > 0) { - process.stderr.write(util.format(...args) + "\n") - } -} -wtfnode.setLogger("info", write) -wtfnode.setLogger("warn", write) -wtfnode.setLogger("error", write) - -let active = false - -/** - * Start logging open handles periodically. This can be used to see what is - * hanging open if anything. - */ -export function setup(): void { - if (active) { - return - } - active = true - - const interval = 5000 - const wtfnodeDump = () => { - wtfnode.dump() - const t = setTimeout(wtfnodeDump, interval) - t.unref() - } - const t = setTimeout(wtfnodeDump, interval) - t.unref() -} From b46859787208c3d2ff108976031172d5a5a88c5b Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 9 Mar 2021 16:33:01 -0700 Subject: [PATCH 03/10] refactor: move e2e tests to test/e2e --- test/{ => e2e}/e2e.test.ts | 2 +- test/{ => e2e}/goHome.test.ts | 8 ++++---- test/{ => e2e}/login.test.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) rename test/{ => e2e}/e2e.test.ts (89%) rename test/{ => e2e}/goHome.test.ts (92%) rename test/{ => e2e}/login.test.ts (93%) diff --git a/test/e2e.test.ts b/test/e2e/e2e.test.ts similarity index 89% rename from test/e2e.test.ts rename to test/e2e/e2e.test.ts index 21df386b..4e60c6eb 100644 --- a/test/e2e.test.ts +++ b/test/e2e/e2e.test.ts @@ -1,5 +1,5 @@ import { chromium, Page, Browser } from "playwright" -import { CODE_SERVER_ADDRESS } from "./constants" +import { CODE_SERVER_ADDRESS } from "../utils/constants" let browser: Browser let page: Page diff --git a/test/goHome.test.ts b/test/e2e/goHome.test.ts similarity index 92% rename from test/goHome.test.ts rename to test/e2e/goHome.test.ts index 40d6a838..b57b2a19 100644 --- a/test/goHome.test.ts +++ b/test/e2e/goHome.test.ts @@ -1,7 +1,7 @@ import { chromium, Page, Browser, BrowserContext, Cookie } from "playwright" -import { hash } from "../src/node/util" -import { CODE_SERVER_ADDRESS, PASSWORD, STORAGE } from "./constants" -import { createCookieIfDoesntExist } from "./helpers" +import { hash } from "../../src/node/util" +import { CODE_SERVER_ADDRESS, PASSWORD, STORAGE, E2E_VIDEO_DIR } from "../utils/constants" +import { createCookieIfDoesntExist } from "../utils/helpers" describe("go home", () => { let browser: Browser @@ -45,7 +45,7 @@ describe("go home", () => { context = await browser.newContext({ storageState: { cookies: maybeUpdatedCookies }, - recordVideo: { dir: "./test/videos/" }, + recordVideo: { dir: E2E_VIDEO_DIR }, }) }) diff --git a/test/login.test.ts b/test/e2e/login.test.ts similarity index 93% rename from test/login.test.ts rename to test/e2e/login.test.ts index b269acbd..ca098904 100644 --- a/test/login.test.ts +++ b/test/e2e/login.test.ts @@ -1,5 +1,5 @@ import { chromium, Page, Browser, BrowserContext } from "playwright" -import { CODE_SERVER_ADDRESS, PASSWORD } from "./constants" +import { CODE_SERVER_ADDRESS, PASSWORD } from "../utils/constants" describe("login", () => { let browser: Browser From cf6fdb90eb69bf5143b233ca177d0b5223359ef7 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 9 Mar 2021 16:33:39 -0700 Subject: [PATCH 04/10] refactor: create test/utils --- test/integration.ts | 21 -------------------- test/{ => utils}/constants.ts | 1 + test/{ => utils}/cssStub.ts | 0 test/{ => utils}/globalSetup.ts | 4 ++-- test/{ => utils}/helpers.ts | 0 test/{ => utils}/httpserver.ts | 6 +++--- test/utils/wtfnode.ts | 35 +++++++++++++++++++++++++++++++++ 7 files changed, 41 insertions(+), 26 deletions(-) delete mode 100644 test/integration.ts rename test/{ => utils}/constants.ts (80%) rename test/{ => utils}/cssStub.ts (100%) rename test/{ => utils}/globalSetup.ts (87%) rename test/{ => utils}/helpers.ts (100%) rename test/{ => utils}/httpserver.ts (95%) create mode 100644 test/utils/wtfnode.ts diff --git a/test/integration.ts b/test/integration.ts deleted file mode 100644 index f829fe5d..00000000 --- a/test/integration.ts +++ /dev/null @@ -1,21 +0,0 @@ -import * as express from "express" -import { createApp } from "../src/node/app" -import { parse, setDefaults, parseConfigFile, DefaultedArgs } from "../src/node/cli" -import { register } from "../src/node/routes" -import * as httpserver from "./httpserver" - -export async function setup( - argv: string[], - configFile?: string, -): Promise<[express.Application, express.Application, httpserver.HttpServer, DefaultedArgs]> { - argv = ["--bind-addr=localhost:0", ...argv] - - const cliArgs = parse(argv) - const configArgs = parseConfigFile(configFile || "", "test/integration.ts") - const args = await setDefaults(cliArgs, configArgs) - - const [app, wsApp, server] = await createApp(args) - await register(app, wsApp, server, args) - - return [app, wsApp, new httpserver.HttpServer(server), args] -} diff --git a/test/constants.ts b/test/utils/constants.ts similarity index 80% rename from test/constants.ts rename to test/utils/constants.ts index ac2250e1..9a750892 100644 --- a/test/constants.ts +++ b/test/utils/constants.ts @@ -1,3 +1,4 @@ export const CODE_SERVER_ADDRESS = process.env.CODE_SERVER_ADDRESS || "http://localhost:8080" export const PASSWORD = process.env.PASSWORD || "e45432jklfdsab" export const STORAGE = process.env.STORAGE || "" +export const E2E_VIDEO_DIR = "./test/e2e/videos" diff --git a/test/cssStub.ts b/test/utils/cssStub.ts similarity index 100% rename from test/cssStub.ts rename to test/utils/cssStub.ts diff --git a/test/globalSetup.ts b/test/utils/globalSetup.ts similarity index 87% rename from test/globalSetup.ts rename to test/utils/globalSetup.ts index 5ef45faa..36b242d7 100644 --- a/test/globalSetup.ts +++ b/test/utils/globalSetup.ts @@ -6,7 +6,7 @@ import { CODE_SERVER_ADDRESS, PASSWORD } from "./constants" import * as wtfnode from "./wtfnode" module.exports = async () => { - console.log("\n🚨 Running Global Setup for Jest Tests") + console.log("\n🚨 Running Global Setup for Jest End-to-End Tests") console.log(" Please hang tight...") const browser = await chromium.launch() const context = await browser.newContext() @@ -30,5 +30,5 @@ module.exports = async () => { await page.close() await browser.close() await context.close() - console.log("✅ Global Setup for Jest Tests is now complete.") + console.log("✅ Global Setup for Jest End-to-End Tests is now complete.") } diff --git a/test/helpers.ts b/test/utils/helpers.ts similarity index 100% rename from test/helpers.ts rename to test/utils/helpers.ts diff --git a/test/httpserver.ts b/test/utils/httpserver.ts similarity index 95% rename from test/httpserver.ts rename to test/utils/httpserver.ts index 399ccda1..a66bbbff 100644 --- a/test/httpserver.ts +++ b/test/utils/httpserver.ts @@ -3,9 +3,9 @@ import * as http from "http" import * as net from "net" import * as nodeFetch from "node-fetch" import Websocket from "ws" -import * as util from "../src/common/util" -import { ensureAddress } from "../src/node/app" -import { handleUpgrade } from "../src/node/wsRouter" +import * as util from "../../src/common/util" +import { ensureAddress } from "../../src/node/app" +import { handleUpgrade } from "../../src/node/wsRouter" // Perhaps an abstraction similar to this should be used in app.ts as well. export class HttpServer { diff --git a/test/utils/wtfnode.ts b/test/utils/wtfnode.ts new file mode 100644 index 00000000..2d31a4e6 --- /dev/null +++ b/test/utils/wtfnode.ts @@ -0,0 +1,35 @@ +import * as util from "util" +import * as wtfnode from "wtfnode" + +// Jest seems to hijack console.log in a way that makes the output difficult to +// read. So we'll write directly to process.stderr instead. +const write = (...args: [any, ...any]) => { + if (args.length > 0) { + process.stderr.write(util.format(...args) + "\n") + } +} +wtfnode.setLogger("info", write) +wtfnode.setLogger("warn", write) +wtfnode.setLogger("error", write) + +let active = false + +/** + * Start logging open handles periodically. This can be used to see what is + * hanging open if anything. + */ +export function setup(): void { + if (active) { + return + } + active = true + + const interval = 5000 + const wtfnodeDump = () => { + wtfnode.dump() + const t = setTimeout(wtfnodeDump, interval) + t.unref() + } + const t = setTimeout(wtfnodeDump, interval) + t.unref() +} From d10da3f7c367402576e6666be7b52279b0457c45 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 9 Mar 2021 16:34:15 -0700 Subject: [PATCH 05/10] refactor: move test-plugin --- test/test-plugin/.eslintrc.yaml | 5 --- test/test-plugin/.gitignore | 1 - test/test-plugin/Makefile | 6 --- test/test-plugin/package.json | 16 ------- test/test-plugin/public/icon.svg | 1 - test/test-plugin/public/index.html | 10 ----- test/test-plugin/src/index.ts | 52 ---------------------- test/test-plugin/tsconfig.json | 71 ------------------------------ test/test-plugin/yarn.lock | 70 ----------------------------- 9 files changed, 232 deletions(-) delete mode 100644 test/test-plugin/.eslintrc.yaml delete mode 100644 test/test-plugin/.gitignore delete mode 100644 test/test-plugin/Makefile delete mode 100644 test/test-plugin/package.json delete mode 100644 test/test-plugin/public/icon.svg delete mode 100644 test/test-plugin/public/index.html delete mode 100644 test/test-plugin/src/index.ts delete mode 100644 test/test-plugin/tsconfig.json delete mode 100644 test/test-plugin/yarn.lock diff --git a/test/test-plugin/.eslintrc.yaml b/test/test-plugin/.eslintrc.yaml deleted file mode 100644 index 67a20fa6..00000000 --- a/test/test-plugin/.eslintrc.yaml +++ /dev/null @@ -1,5 +0,0 @@ -settings: - import/resolver: - alias: - map: - - [code-server, ./typings/pluginapi.d.ts] diff --git a/test/test-plugin/.gitignore b/test/test-plugin/.gitignore deleted file mode 100644 index 1fcb1529..00000000 --- a/test/test-plugin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -out diff --git a/test/test-plugin/Makefile b/test/test-plugin/Makefile deleted file mode 100644 index d01aa80a..00000000 --- a/test/test-plugin/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -out/index.js: src/index.ts - # Typescript always emits, even on errors. - yarn build || rm out/index.js - -node_modules: package.json yarn.lock - yarn diff --git a/test/test-plugin/package.json b/test/test-plugin/package.json deleted file mode 100644 index 2fe72378..00000000 --- a/test/test-plugin/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "private": true, - "name": "test-plugin", - "version": "1.0.0", - "engines": { - "code-server": "^3.7.0" - }, - "main": "out/index.js", - "devDependencies": { - "@types/express": "^4.17.8", - "typescript": "^4.0.5" - }, - "scripts": { - "build": "tsc" - } -} diff --git a/test/test-plugin/public/icon.svg b/test/test-plugin/public/icon.svg deleted file mode 100644 index 25b9cf04..00000000 --- a/test/test-plugin/public/icon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/test/test-plugin/public/index.html b/test/test-plugin/public/index.html deleted file mode 100644 index 3485f18e..00000000 --- a/test/test-plugin/public/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Test Plugin - - -

Welcome to the test plugin!

- - diff --git a/test/test-plugin/src/index.ts b/test/test-plugin/src/index.ts deleted file mode 100644 index 772b59d8..00000000 --- a/test/test-plugin/src/index.ts +++ /dev/null @@ -1,52 +0,0 @@ -import * as cs from "code-server" -import * as fspath from "path" - -export const plugin: cs.Plugin = { - displayName: "Test Plugin", - routerPath: "/test-plugin", - homepageURL: "https://example.com", - description: "Plugin used in code-server tests.", - - init(config) { - config.logger.debug("test-plugin loaded!") - }, - - router() { - const r = cs.express.Router() - r.get("/test-app", (_, res) => { - res.sendFile(fspath.resolve(__dirname, "../public/index.html")) - }) - r.get("/goland/icon.svg", (_, res) => { - res.sendFile(fspath.resolve(__dirname, "../public/icon.svg")) - }) - r.get("/error", () => { - throw new cs.HttpError("error", cs.HttpCode.LargePayload) - }) - return r - }, - - wsRouter() { - const wr = cs.WsRouter() - wr.ws("/test-app", (req) => { - cs.wss.handleUpgrade(req, req.ws, req.head, (ws) => { - req.ws.resume() - ws.send("hello") - }) - }) - return wr - }, - - applications() { - return [ - { - name: "Test App", - version: "4.0.0", - iconPath: "/icon.svg", - path: "/test-app", - - description: "This app does XYZ.", - homepageURL: "https://example.com", - }, - ] - }, -} diff --git a/test/test-plugin/tsconfig.json b/test/test-plugin/tsconfig.json deleted file mode 100644 index 5afea81b..00000000 --- a/test/test-plugin/tsconfig.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ - "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, - "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - // "lib": [], /* Specify library files to be included in the compilation. */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./out" /* Redirect output structure to the directory. */, - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - "baseUrl": "./" /* Base directory to resolve non-absolute module names. */, - "paths": { - "code-server": ["../../typings/pluginapi"] - } /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */, - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true /* Skip type checking of declaration files. */, - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ - } -} diff --git a/test/test-plugin/yarn.lock b/test/test-plugin/yarn.lock deleted file mode 100644 index f295de1e..00000000 --- a/test/test-plugin/yarn.lock +++ /dev/null @@ -1,70 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@types/body-parser@*": - version "1.19.0" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" - integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.33" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" - integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== - dependencies: - "@types/node" "*" - -"@types/express-serve-static-core@*": - version "4.17.13" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.13.tgz#d9af025e925fc8b089be37423b8d1eac781be084" - integrity sha512-RgDi5a4nuzam073lRGKTUIaL3eF2+H7LJvJ8eUnCI0wA6SNjXc44DCmWNiTLs/AZ7QlsFWZiw/gTG3nSQGL0fA== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - -"@types/express@^4.17.8": - version "4.17.8" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.8.tgz#3df4293293317e61c60137d273a2e96cd8d5f27a" - integrity sha512-wLhcKh3PMlyA2cNAB9sjM1BntnhPMiM0JOBwPBqttjHev2428MLEB4AYVN+d8s2iyCVZac+o41Pflm/ZH5vLXQ== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "*" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/mime@*": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a" - integrity sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q== - -"@types/node@*": - version "14.14.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.6.tgz#146d3da57b3c636cc0d1769396ce1cfa8991147f" - integrity sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw== - -"@types/qs@*": - version "6.9.5" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.5.tgz#434711bdd49eb5ee69d90c1d67c354a9a8ecb18b" - integrity sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ== - -"@types/range-parser@*": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" - integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== - -"@types/serve-static@*": - version "1.13.6" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.6.tgz#866b1b8dec41c36e28c7be40ac725b88be43c5c1" - integrity sha512-nuRJmv7jW7VmCVTn+IgYDkkbbDGyIINOeu/G0d74X3lm6E5KfMeQPJhxIt1ayQeQB3cSxvYs1RA/wipYoFB4EA== - dependencies: - "@types/mime" "*" - "@types/node" "*" - -typescript@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389" - integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ== From 529d69e8e8130381426471c2821a1e30bb138c95 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 9 Mar 2021 16:35:25 -0700 Subject: [PATCH 06/10] refactor: add scripts to separate unit, e2e tests --- ci/README.md | 18 +++++++++++------- ci/dev/ci.sh | 2 +- ci/dev/{test.sh => test-e2e.sh} | 5 +---- ci/dev/test-unit.sh | 15 +++++++++++++++ ci/steps/test-e2e.sh | 12 ++++++++++++ ci/steps/{test.sh => test-unit.sh} | 2 +- package.json | 11 +++++------ 7 files changed, 46 insertions(+), 19 deletions(-) rename ci/dev/{test.sh => test-e2e.sh} (85%) create mode 100755 ci/dev/test-unit.sh create mode 100755 ci/steps/test-e2e.sh rename ci/steps/{test.sh => test-unit.sh} (87%) diff --git a/ci/README.md b/ci/README.md index 0bb983ef..19d6778e 100644 --- a/ci/README.md +++ b/ci/README.md @@ -52,7 +52,7 @@ Make sure you have `$GITHUB_TOKEN` set and [hub](https://github.com/github/hub) Currently, we run a command to manually generate the code coverage shield. Follow these steps: -1. Run `yarn test` and make sure all the tests are passing +1. Run `yarn test:unit` and make sure all the tests are passing 2. Run `yarn badges` 3. Go into the README and change the color from `red` to `green` in this line: @@ -72,8 +72,10 @@ This directory contains scripts used for the development of code-server. - Runs formatters. - [./ci/dev/lint.sh](./dev/lint.sh) (`yarn lint`) - Runs linters. -- [./ci/dev/test.sh](./dev/test.sh) (`yarn test`) - - Runs tests. +- [./ci/dev/test-unit.sh](./dev/test-unit.sh) (`yarn test:unit`) + - Runs unit tests. +- [./ci/dev/test-e2e.sh](./dev/test-e2e.sh) (`yarn test:e2e`) + - Runs end-to-end tests. - [./ci/dev/ci.sh](./dev/ci.sh) (`yarn ci`) - Runs `yarn fmt`, `yarn lint` and `yarn test`. - [./ci/dev/watch.ts](./dev/watch.ts) (`yarn watch`) @@ -142,11 +144,13 @@ This directory contains the scripts used in CI. Helps avoid clobbering the CI configuration. - [./steps/fmt.sh](./steps/fmt.sh) - - Runs `yarn fmt` after ensuring VS Code is patched. + - Runs `yarn fmt`. - [./steps/lint.sh](./steps/lint.sh) - - Runs `yarn lint` after ensuring VS Code is patched. -- [./steps/test.sh](./steps/test.sh) - - Runs `yarn test` after ensuring VS Code is patched. + - Runs `yarn lint`. +- [./steps/test-unit.sh](./steps/test-unit.sh) + - Runs `yarn test:unit`. +- [./steps/test-e2e.sh](./steps/test-e2e.sh) + - Runs `yarn test:e2e`. - [./steps/release.sh](./steps/release.sh) - Runs the release process. - Generates the npm package at `./release`. diff --git a/ci/dev/ci.sh b/ci/dev/ci.sh index e9268286..92265a97 100755 --- a/ci/dev/ci.sh +++ b/ci/dev/ci.sh @@ -6,7 +6,7 @@ main() { yarn fmt yarn lint - yarn test + yarn test:unit } main "$@" diff --git a/ci/dev/test.sh b/ci/dev/test-e2e.sh similarity index 85% rename from ci/dev/test.sh rename to ci/dev/test-e2e.sh index 82f6ad36..d81d25cb 100755 --- a/ci/dev/test.sh +++ b/ci/dev/test-e2e.sh @@ -3,12 +3,9 @@ set -euo pipefail main() { cd "$(dirname "$0")/../.." - cd test/test-plugin - make -s out/index.js # 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. - cd "$OLDPWD" if [[ -z ${PASSWORD-} ]] || [[ -z ${CODE_SERVER_ADDRESS-} ]]; then echo "The end-to-end testing suites rely on your local environment" echo -e "\n" @@ -21,7 +18,7 @@ main() { echo -e "\n" exit 1 fi - CS_DISABLE_PLUGINS=true ./test/node_modules/.bin/jest "$@" + CS_DISABLE_PLUGINS=true ./test/node_modules/.bin/jest "$@" --config ./test/jest.e2e.config.ts } main "$@" diff --git a/ci/dev/test-unit.sh b/ci/dev/test-unit.sh new file mode 100755 index 00000000..f2e76ee5 --- /dev/null +++ b/ci/dev/test-unit.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -euo pipefail + +main() { + cd "$(dirname "$0")/../.." + cd test/unit/test-plugin + make -s out/index.js + # 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. + cd "$OLDPWD" + CS_DISABLE_PLUGINS=true ./test/node_modules/.bin/jest "$@" +} + +main "$@" diff --git a/ci/steps/test-e2e.sh b/ci/steps/test-e2e.sh new file mode 100755 index 00000000..c1aa148a --- /dev/null +++ b/ci/steps/test-e2e.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +main() { + cd "$(dirname "$0")/../.." + + ./release-packages/code-server*-linux-amd64/bin/code-server --home $CODE_SERVER_ADDRESS/healthz & + yarn --frozen-lockfile + yarn test:e2e +} + +main "$@" diff --git a/ci/steps/test.sh b/ci/steps/test-unit.sh similarity index 87% rename from ci/steps/test.sh rename to ci/steps/test-unit.sh index 72aa3ca2..77fd547c 100755 --- a/ci/steps/test.sh +++ b/ci/steps/test-unit.sh @@ -6,7 +6,7 @@ main() { yarn --frozen-lockfile - yarn test + yarn test:unit } main "$@" diff --git a/package.json b/package.json index 6c3eebdf..50541dda 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,9 @@ "release:standalone": "./ci/build/build-standalone-release.sh", "release:github-draft": "./ci/build/release-github-draft.sh", "release:github-assets": "./ci/build/release-github-assets.sh", - "test:e2e": "./ci/dev/test.sh", + "test:e2e": "./ci/dev/test-e2e.sh", "test:standalone-release": "./ci/build/test-standalone-release.sh", - "test:unit": "./ci/dev/test.sh", + "test:unit": "./ci/dev/test-unit.sh", "package": "./ci/build/build-packages.sh", "postinstall": "./ci/dev/postinstall.sh", "update:vscode": "./ci/dev/update-vscode.sh", @@ -126,7 +126,8 @@ "testPathIgnorePatterns": [ "node_modules", "lib", - "out" + "out", + "test/e2e" ], "collectCoverage": true, "collectCoverageFrom": [ @@ -146,8 +147,6 @@ "lines": 40 } }, - "testTimeout": 30000, - "globalSetup": "/test/globalSetup.ts", "modulePathIgnorePatterns": [ "/lib/vscode", "/release-packages", @@ -158,7 +157,7 @@ "/release-images" ], "moduleNameMapper": { - "^.+\\.(css|less)$": "/test/cssStub.ts" + "^.+\\.(css|less)$": "/test/utils/cssStub.ts" } } } From 6fd30d91eabcfdeebc701430bdce168e0c3bca28 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 9 Mar 2021 16:35:34 -0700 Subject: [PATCH 07/10] feat: add jest e2e config --- test/jest.e2e.config.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 test/jest.e2e.config.ts diff --git a/test/jest.e2e.config.ts b/test/jest.e2e.config.ts new file mode 100644 index 00000000..01f9b607 --- /dev/null +++ b/test/jest.e2e.config.ts @@ -0,0 +1,22 @@ +// jest.config.ts +import type { Config } from "@jest/types" + +const config: Config.InitialOptions = { + transform: { + "^.+\\.ts$": "/node_modules/ts-jest", + }, + globalSetup: "/utils/globalSetup.ts", + testEnvironment: "node", + testPathIgnorePatterns: ["node_modules", "lib", "out", "test/unit"], + testTimeout: 30000, + modulePathIgnorePatterns: [ + "/../lib/vscode", + "/../release-packages", + "/../release", + "/../release-standalone", + "/../release-npm-package", + "/../release-gcp", + "/../release-images", + ], +} +export default config From aeaf11ced60805b9882d52bacf9c590e79e88ea1 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 9 Mar 2021 16:35:54 -0700 Subject: [PATCH 08/10] refactor: update ci.yaml, test:unit and test:e2e --- .github/workflows/ci.yaml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c861a808..8bef3db6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -27,7 +27,16 @@ jobs: with: args: ./ci/steps/lint.sh - test: + test-unit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Run unit tests + uses: ./ci/images/debian10 + with: + args: ./ci/steps/test-unit.sh + + test-e2e: needs: linux-amd64 runs-on: ubuntu-latest env: @@ -45,18 +54,16 @@ jobs: cd release-packages && tar -xzf code-server*-linux-amd64.tar.gz - uses: microsoft/playwright-github-action@v1 - name: Install dependencies and run tests - run: | - ./release-packages/code-server*-linux-amd64/bin/code-server --home $CODE_SERVER_ADDRESS/healthz & - yarn --frozen-lockfile - yarn test + with: + args: ./ci/steps/test-e2e.sh - name: Upload test artifacts if: always() uses: actions/upload-artifact@v2 with: name: test-videos - path: ./test/videos + path: ./test/e2e//videos - name: Remove release packages and test artifacts - run: rm -rf ./release-packages ./test/videos + run: rm -rf ./release-packages ./test/e2e/videos release: runs-on: ubuntu-latest From 9ee2556dd1ca199d46c6250d4eeacdbe6548daa6 Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Tue, 9 Mar 2021 16:36:56 -0700 Subject: [PATCH 09/10] chore: update gitignore with test dirs --- .github/workflows/ci.yaml | 11 ++++++----- .gitignore | 4 ++-- ci/steps/test-e2e.sh | 2 +- test/utils/integration.ts | 21 +++++++++++++++++++++ 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 test/utils/integration.ts diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8bef3db6..914ad567 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -35,7 +35,6 @@ jobs: uses: ./ci/images/debian10 with: args: ./ci/steps/test-unit.sh - test-e2e: needs: linux-amd64 runs-on: ubuntu-latest @@ -53,15 +52,17 @@ jobs: run: | cd release-packages && tar -xzf code-server*-linux-amd64.tar.gz - uses: microsoft/playwright-github-action@v1 - - name: Install dependencies and run tests - with: - args: ./ci/steps/test-e2e.sh + - name: Install dependencies and run end-to-end tests + run: | + ./release-packages/code-server*-linux-amd64/bin/code-server --home $CODE_SERVER_ADDRESS/healthz & + yarn --frozen-lockfile + yarn test:e2e - name: Upload test artifacts if: always() uses: actions/upload-artifact@v2 with: name: test-videos - path: ./test/e2e//videos + path: ./test/e2e/videos - name: Remove release packages and test artifacts run: rm -rf ./release-packages ./test/e2e/videos diff --git a/.gitignore b/.gitignore index e49888f4..45da9b42 100644 --- a/.gitignore +++ b/.gitignore @@ -16,5 +16,5 @@ node-* .home coverage **/.DS_Store -test/videos -test/screenshots +test/e2e/videos +test/e2e/screenshots diff --git a/ci/steps/test-e2e.sh b/ci/steps/test-e2e.sh index c1aa148a..c43fbd07 100755 --- a/ci/steps/test-e2e.sh +++ b/ci/steps/test-e2e.sh @@ -4,7 +4,7 @@ set -euo pipefail main() { cd "$(dirname "$0")/../.." - ./release-packages/code-server*-linux-amd64/bin/code-server --home $CODE_SERVER_ADDRESS/healthz & + "./release-packages/code-server*-linux-amd64/bin/code-server" --home "$CODE_SERVER_ADDRESS"/healthz & yarn --frozen-lockfile yarn test:e2e } diff --git a/test/utils/integration.ts b/test/utils/integration.ts new file mode 100644 index 00000000..c5101d0f --- /dev/null +++ b/test/utils/integration.ts @@ -0,0 +1,21 @@ +import * as express from "express" +import { createApp } from "../../src/node/app" +import { parse, setDefaults, parseConfigFile, DefaultedArgs } from "../../src/node/cli" +import { register } from "../../src/node/routes" +import * as httpserver from "./httpserver" + +export async function setup( + argv: string[], + configFile?: string, +): Promise<[express.Application, express.Application, httpserver.HttpServer, DefaultedArgs]> { + argv = ["--bind-addr=localhost:0", ...argv] + + const cliArgs = parse(argv) + const configArgs = parseConfigFile(configFile || "", "test/integration.ts") + const args = await setDefaults(cliArgs, configArgs) + + const [app, wsApp, server] = await createApp(args) + await register(app, wsApp, server, args) + + return [app, wsApp, new httpserver.HttpServer(server), args] +} From 7e23575978d68455e1ae926bea4391508e98b72c Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Wed, 10 Mar 2021 12:23:36 -0700 Subject: [PATCH 10/10] chore: update code-server path in tsconfig --- test/unit/test-plugin/tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/test-plugin/tsconfig.json b/test/unit/test-plugin/tsconfig.json index 5afea81b..bb30a1ad 100644 --- a/test/unit/test-plugin/tsconfig.json +++ b/test/unit/test-plugin/tsconfig.json @@ -44,7 +44,7 @@ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ "baseUrl": "./" /* Base directory to resolve non-absolute module names. */, "paths": { - "code-server": ["../../typings/pluginapi"] + "code-server": ["../../../typings/pluginapi"] } /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */, // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */