mirror of https://github.com/coder/coder.git
chore: add more e2e template settings tests (#12717)
This commit is contained in:
parent
8cf1e84bb5
commit
f3cfe10c26
|
@ -472,11 +472,19 @@ jobs:
|
|||
- run: pnpm playwright:install
|
||||
working-directory: site
|
||||
|
||||
- run: pnpm playwright:test --workers 1
|
||||
# Run tests that don't require an enterprise license without an enterprise license
|
||||
- run: pnpm playwright:test --forbid-only --workers 1
|
||||
env:
|
||||
DEBUG: pw:api
|
||||
working-directory: site
|
||||
|
||||
# Run all of the tests with an enterprise license
|
||||
- run: pnpm playwright:test --forbid-only --workers 1
|
||||
env:
|
||||
DEBUG: pw:api
|
||||
CODER_E2E_ENTERPRISE_LICENSE: ${{ secrets.CODER_E2E_ENTERPRISE_LICENSE }}
|
||||
working-directory: site
|
||||
|
||||
- name: Upload Playwright Failed Tests
|
||||
if: always() && github.actor != 'dependabot[bot]' && runner.os == 'Linux' && !github.event.pull_request.head.repo.fork
|
||||
uses: actions/upload-artifact@v4
|
||||
|
|
|
@ -3,7 +3,7 @@ set -euo pipefail
|
|||
|
||||
workspace=${1:-}
|
||||
coder_repo=${2:-.}
|
||||
port=${3:-3000}
|
||||
port=${3:-3111}
|
||||
|
||||
if [[ -z "${workspace}" ]]; then
|
||||
echo "Usage: $0 <workspace> [workspace coder/coder dir] [e2e port]"
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
import * as path from "path";
|
||||
|
||||
export const coderMain = path.join(__dirname, "../../enterprise/cmd/coder");
|
||||
|
||||
// Default port from the server
|
||||
export const coderPort = process.env.CODER_E2E_PORT
|
||||
? Number(process.env.CODER_E2E_PORT)
|
||||
|
@ -28,3 +32,5 @@ export const gitAuth = {
|
|||
validatePath: "/validate",
|
||||
installationsPath: "/installations",
|
||||
};
|
||||
|
||||
export const enterpriseLicense = process.env.CODER_E2E_ENTERPRISE_LICENSE ?? "";
|
||||
|
|
|
@ -6,6 +6,7 @@ import { storageState } from "./playwright.config";
|
|||
test("setup first user", async ({ page }) => {
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
|
||||
// Setup first user
|
||||
await page.getByLabel(Language.usernameLabel).fill(constants.username);
|
||||
await page.getByLabel(Language.emailLabel).fill(constants.email);
|
||||
await page.getByLabel(Language.passwordLabel).fill(constants.password);
|
||||
|
@ -15,4 +16,15 @@ test("setup first user", async ({ page }) => {
|
|||
await page.context().storageState({ path: storageState });
|
||||
|
||||
await page.getByTestId("button-select-template").isVisible();
|
||||
|
||||
// Setup license
|
||||
if (constants.enterpriseLicense) {
|
||||
await page.goto("/deployment/licenses", { waitUntil: "domcontentloaded" });
|
||||
|
||||
await page.getByText("Add a license").click();
|
||||
await page.getByRole("textbox").fill(constants.enterpriseLicense);
|
||||
await page.getByText("Upload License").click();
|
||||
|
||||
await page.getByText("You have successfully added a license").isVisible();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { type BrowserContext, expect, type Page } from "@playwright/test";
|
||||
import { type BrowserContext, expect, type Page, test } from "@playwright/test";
|
||||
import axios from "axios";
|
||||
import { type ChildProcess, exec, spawn } from "child_process";
|
||||
import { randomUUID } from "crypto";
|
||||
|
@ -12,7 +12,13 @@ import type {
|
|||
UpdateTemplateMeta,
|
||||
} from "api/typesGenerated";
|
||||
import { TarWriter } from "utils/tar";
|
||||
import { agentPProfPort, coderPort, prometheusPort } from "./constants";
|
||||
import {
|
||||
agentPProfPort,
|
||||
coderMain,
|
||||
coderPort,
|
||||
enterpriseLicense,
|
||||
prometheusPort,
|
||||
} from "./constants";
|
||||
import {
|
||||
Agent,
|
||||
type App,
|
||||
|
@ -25,6 +31,11 @@ import {
|
|||
type RichParameter,
|
||||
} from "./provisionerGenerated";
|
||||
|
||||
// requiresEnterpriseLicense will skip the test if we're not running with an enterprise license
|
||||
export function requiresEnterpriseLicense() {
|
||||
test.skip(!enterpriseLicense);
|
||||
}
|
||||
|
||||
// createWorkspace creates a workspace for a template.
|
||||
// It does not wait for it to be running, but it does navigate to the page.
|
||||
export const createWorkspace = async (
|
||||
|
@ -147,7 +158,7 @@ export const sshIntoWorkspace = async (
|
|||
binaryArgs: string[] = [],
|
||||
): Promise<ssh.Client> => {
|
||||
if (binaryPath === "go") {
|
||||
binaryArgs = ["run", coderMainPath()];
|
||||
binaryArgs = ["run", coderMain];
|
||||
}
|
||||
const sessionToken = await findSessionToken(page);
|
||||
return new Promise<ssh.Client>((resolve, reject) => {
|
||||
|
@ -229,7 +240,7 @@ export const startAgent = async (
|
|||
page: Page,
|
||||
token: string,
|
||||
): Promise<ChildProcess> => {
|
||||
return startAgentWithCommand(page, token, "go", "run", coderMainPath());
|
||||
return startAgentWithCommand(page, token, "go", "run", coderMain);
|
||||
};
|
||||
|
||||
// downloadCoderVersion downloads the version provided into a temporary dir and
|
||||
|
@ -358,18 +369,6 @@ const waitUntilUrlIsNotResponding = async (url: string) => {
|
|||
);
|
||||
};
|
||||
|
||||
const coderMainPath = (): string => {
|
||||
return path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"..",
|
||||
"enterprise",
|
||||
"cmd",
|
||||
"coder",
|
||||
"main.go",
|
||||
);
|
||||
};
|
||||
|
||||
// Allows users to more easily define properties they want for agents and resources!
|
||||
type RecursivePartial<T> = {
|
||||
[P in keyof T]?: T[P] extends (infer U)[]
|
||||
|
@ -686,7 +685,7 @@ export const updateTemplate = async (
|
|||
"go",
|
||||
[
|
||||
"run",
|
||||
coderMainPath(),
|
||||
coderMain,
|
||||
"templates",
|
||||
"push",
|
||||
"--test.provisioner",
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import { defineConfig } from "@playwright/test";
|
||||
import path from "path";
|
||||
import { coderPort, coderdPProfPort, gitAuth } from "./constants";
|
||||
import * as path from "path";
|
||||
import { coderMain, coderPort, coderdPProfPort, gitAuth } from "./constants";
|
||||
|
||||
export const wsEndpoint = process.env.CODER_E2E_WS_ENDPOINT;
|
||||
|
||||
const coderMain = path.join(__dirname, "../../enterprise/cmd/coder");
|
||||
|
||||
// This is where auth cookies are stored!
|
||||
export const storageState = path.join(__dirname, ".auth.json");
|
||||
|
||||
|
@ -16,16 +14,14 @@ const localURL = (port: number, path: string): string => {
|
|||
export default defineConfig({
|
||||
projects: [
|
||||
{
|
||||
name: "setup",
|
||||
name: "testsSetup",
|
||||
testMatch: /global.setup\.ts/,
|
||||
},
|
||||
{
|
||||
name: "tests",
|
||||
testMatch: /.*\.spec\.ts/,
|
||||
dependencies: ["setup"],
|
||||
use: {
|
||||
storageState: storageState,
|
||||
},
|
||||
dependencies: ["testsSetup"],
|
||||
use: { storageState },
|
||||
timeout: 60_000,
|
||||
},
|
||||
],
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import { test } from "@playwright/test";
|
||||
import { createTemplate, updateTemplateSettings } from "../helpers";
|
||||
import { expect, test } from "@playwright/test";
|
||||
import {
|
||||
createTemplate,
|
||||
requiresEnterpriseLicense,
|
||||
updateTemplateSettings,
|
||||
} from "../helpers";
|
||||
|
||||
test("template update with new name redirects on successful submit", async ({
|
||||
page,
|
||||
|
@ -10,3 +14,24 @@ test("template update with new name redirects on successful submit", async ({
|
|||
name: "new-name",
|
||||
});
|
||||
});
|
||||
|
||||
test("require latest version", async ({ page }) => {
|
||||
requiresEnterpriseLicense();
|
||||
|
||||
const templateName = await createTemplate(page);
|
||||
|
||||
await page.goto(`/templates/${templateName}/settings`, {
|
||||
waitUntil: "domcontentloaded",
|
||||
});
|
||||
await expect(page).toHaveURL(`/templates/${templateName}/settings`);
|
||||
let checkbox = await page.waitForSelector("#require_active_version");
|
||||
await checkbox.click();
|
||||
await page.getByTestId("form-submit").click();
|
||||
|
||||
await page.goto(`/templates/${templateName}/settings`, {
|
||||
waitUntil: "domcontentloaded",
|
||||
});
|
||||
checkbox = await page.waitForSelector("#require_active_version");
|
||||
await checkbox.scrollIntoViewIfNeeded();
|
||||
expect(await checkbox.isChecked()).toBe(true);
|
||||
});
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@octokit/types": "12.3.0",
|
||||
"@playwright/test": "1.39.0",
|
||||
"@playwright/test": "1.42.1",
|
||||
"@storybook/addon-actions": "7.6.11",
|
||||
"@storybook/addon-essentials": "7.6.11",
|
||||
"@storybook/addon-interactions": "7.6.11",
|
||||
|
|
|
@ -204,8 +204,8 @@ devDependencies:
|
|||
specifier: 12.3.0
|
||||
version: 12.3.0
|
||||
'@playwright/test':
|
||||
specifier: 1.39.0
|
||||
version: 1.39.0
|
||||
specifier: 1.42.1
|
||||
version: 1.42.1
|
||||
'@storybook/addon-actions':
|
||||
specifier: 7.6.11
|
||||
version: 7.6.11
|
||||
|
@ -3064,12 +3064,12 @@ packages:
|
|||
dev: true
|
||||
optional: true
|
||||
|
||||
/@playwright/test@1.39.0:
|
||||
resolution: {integrity: sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==}
|
||||
/@playwright/test@1.42.1:
|
||||
resolution: {integrity: sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==}
|
||||
engines: {node: '>=16'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
playwright: 1.39.0
|
||||
playwright: 1.42.1
|
||||
dev: true
|
||||
|
||||
/@popperjs/core@2.11.8:
|
||||
|
@ -11478,18 +11478,18 @@ packages:
|
|||
find-up: 5.0.0
|
||||
dev: true
|
||||
|
||||
/playwright-core@1.39.0:
|
||||
resolution: {integrity: sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==}
|
||||
/playwright-core@1.42.1:
|
||||
resolution: {integrity: sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==}
|
||||
engines: {node: '>=16'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/playwright@1.39.0:
|
||||
resolution: {integrity: sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==}
|
||||
/playwright@1.42.1:
|
||||
resolution: {integrity: sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==}
|
||||
engines: {node: '>=16'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
playwright-core: 1.39.0
|
||||
playwright-core: 1.42.1
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
|
Loading…
Reference in New Issue