Merge branch 'main' into jsjoeio/upgrade-vscode-1.54
This commit is contained in:
@ -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
|
@ -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
|
22
test/jest.e2e.config.ts
Normal file
22
test/jest.e2e.config.ts
Normal file
@ -0,0 +1,22 @@
|
||||
// jest.config.ts
|
||||
import type { Config } from "@jest/types"
|
||||
|
||||
const config: Config.InitialOptions = {
|
||||
transform: {
|
||||
"^.+\\.ts$": "<rootDir>/node_modules/ts-jest",
|
||||
},
|
||||
globalSetup: "<rootDir>/utils/globalSetup.ts",
|
||||
testEnvironment: "node",
|
||||
testPathIgnorePatterns: ["node_modules", "lib", "out", "test/unit"],
|
||||
testTimeout: 30000,
|
||||
modulePathIgnorePatterns: [
|
||||
"<rootDir>/../lib/vscode",
|
||||
"<rootDir>/../release-packages",
|
||||
"<rootDir>/../release",
|
||||
"<rootDir>/../release-standalone",
|
||||
"<rootDir>/../release-npm-package",
|
||||
"<rootDir>/../release-gcp",
|
||||
"<rootDir>/../release-images",
|
||||
],
|
||||
}
|
||||
export default config
|
@ -1,91 +0,0 @@
|
||||
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"
|
||||
|
||||
describe("Open Help > About", () => {
|
||||
let browser: Browser
|
||||
let page: Page
|
||||
let context: BrowserContext
|
||||
|
||||
beforeAll(async () => {
|
||||
browser = await chromium.launch()
|
||||
// Create a new context with the saved storage state
|
||||
const storageState = JSON.parse(STORAGE) || {}
|
||||
|
||||
const cookieToStore = {
|
||||
sameSite: "Lax" as const,
|
||||
name: "key",
|
||||
value: hash(PASSWORD),
|
||||
domain: "localhost",
|
||||
path: "/",
|
||||
expires: -1,
|
||||
httpOnly: false,
|
||||
secure: false,
|
||||
}
|
||||
|
||||
// For some odd reason, the login method used in globalSetup.ts doesn't always work
|
||||
// I don't know if it's on playwright clearing our cookies by accident
|
||||
// or if it's our cookies disappearing.
|
||||
// This means we need an additional check to make sure we're logged in.
|
||||
// We do this by manually adding the cookie to the browser environment
|
||||
// if it's not there at the time the test starts
|
||||
const cookies: Cookie[] = storageState.cookies || []
|
||||
// If the cookie exists in cookies then
|
||||
// this will return the cookies with no changes
|
||||
// otherwise if it doesn't exist, it will create it
|
||||
// hence the name maybeUpdatedCookies
|
||||
//
|
||||
// TODO(@jsjoeio)
|
||||
// The playwright storage thing sometimes works and sometimes doesn't. We should investigate this further
|
||||
// at some point.
|
||||
// See discussion: https://github.com/cdr/code-server/pull/2648#discussion_r575434946
|
||||
|
||||
const maybeUpdatedCookies = createCookieIfDoesntExist(cookies, cookieToStore)
|
||||
|
||||
context = await browser.newContext({
|
||||
storageState: { cookies: maybeUpdatedCookies },
|
||||
recordVideo: { dir: "./test/videos/" },
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
// Remove password from local storage
|
||||
await context.clearCookies()
|
||||
|
||||
await context.close()
|
||||
await browser.close()
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
page = await context.newPage()
|
||||
})
|
||||
|
||||
it("should see a 'Help' then 'About' button in the Application Menu that opens a dialog", async () => {
|
||||
// waitUntil: "domcontentloaded"
|
||||
// In case the page takes a long time to load
|
||||
await page.goto(CODE_SERVER_ADDRESS, { waitUntil: "domcontentloaded" })
|
||||
|
||||
// Make sure the editor actually loaded
|
||||
expect(await page.isVisible("div.monaco-workbench"))
|
||||
|
||||
// Click the Application menu
|
||||
await page.click("[aria-label='Application Menu']")
|
||||
// See the Help button
|
||||
const helpButton = "a.action-menu-item span[aria-label='Help']"
|
||||
expect(await page.isVisible(helpButton))
|
||||
|
||||
// Hover the helpButton
|
||||
await page.hover(helpButton)
|
||||
|
||||
// see the About button and click it
|
||||
const aboutButton = "a.action-menu-item span[aria-label='About']"
|
||||
expect(await page.isVisible(aboutButton))
|
||||
// NOTE: it won't work unless you hover it first
|
||||
await page.hover(aboutButton)
|
||||
await page.click(aboutButton)
|
||||
|
||||
const codeServerText = "text=code-server"
|
||||
expect(await page.isVisible(codeServerText))
|
||||
})
|
||||
})
|
@ -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<T> = {
|
||||
-readonly [P in keyof T]: T[P]
|
@ -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", () => {
|
@ -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
|
@ -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
|
@ -1,4 +1,4 @@
|
||||
import { HttpCode, HttpError } from "../src/common/http"
|
||||
import { HttpCode, HttpError } from "../../src/common/http"
|
||||
|
||||
describe("http", () => {
|
||||
describe("HttpCode", () => {
|
@ -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.
|
@ -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()
|
@ -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")
|
@ -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
|
@ -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()
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
@ -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. */
|
@ -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"
|
@ -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<Location, "pathname" | "origin">
|
||||
|
||||
// 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", () => {
|
@ -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"
|
@ -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.")
|
||||
}
|
@ -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 {
|
@ -1,7 +1,7 @@
|
||||
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 { 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(
|
Reference in New Issue
Block a user