|
| 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 | +}) |
0 commit comments