Skip to content

Commit f3cfe10

Browse files
authored
chore: add more e2e template settings tests (#12717)
1 parent 8cf1e84 commit f3cfe10

File tree

9 files changed

+87
-41
lines changed

9 files changed

+87
-41
lines changed

.github/workflows/ci.yaml

+9-1
Original file line numberDiff line numberDiff line change
@@ -472,11 +472,19 @@ jobs:
472472
- run: pnpm playwright:install
473473
working-directory: site
474474

475-
- run: pnpm playwright:test --workers 1
475+
# Run tests that don't require an enterprise license without an enterprise license
476+
- run: pnpm playwright:test --forbid-only --workers 1
476477
env:
477478
DEBUG: pw:api
478479
working-directory: site
479480

481+
# Run all of the tests with an enterprise license
482+
- run: pnpm playwright:test --forbid-only --workers 1
483+
env:
484+
DEBUG: pw:api
485+
CODER_E2E_ENTERPRISE_LICENSE: ${{ secrets.CODER_E2E_ENTERPRISE_LICENSE }}
486+
working-directory: site
487+
480488
- name: Upload Playwright Failed Tests
481489
if: always() && github.actor != 'dependabot[bot]' && runner.os == 'Linux' && !github.event.pull_request.head.repo.fork
482490
uses: actions/upload-artifact@v4

scripts/remote_playwright.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ set -euo pipefail
33

44
workspace=${1:-}
55
coder_repo=${2:-.}
6-
port=${3:-3000}
6+
port=${3:-3111}
77

88
if [[ -z "${workspace}" ]]; then
99
echo "Usage: $0 <workspace> [workspace coder/coder dir] [e2e port]"

site/e2e/constants.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import * as path from "path";
2+
3+
export const coderMain = path.join(__dirname, "../../enterprise/cmd/coder");
4+
15
// Default port from the server
26
export const coderPort = process.env.CODER_E2E_PORT
37
? Number(process.env.CODER_E2E_PORT)
@@ -28,3 +32,5 @@ export const gitAuth = {
2832
validatePath: "/validate",
2933
installationsPath: "/installations",
3034
};
35+
36+
export const enterpriseLicense = process.env.CODER_E2E_ENTERPRISE_LICENSE ?? "";

site/e2e/global.setup.ts

+12
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { storageState } from "./playwright.config";
66
test("setup first user", async ({ page }) => {
77
await page.goto("/", { waitUntil: "domcontentloaded" });
88

9+
// Setup first user
910
await page.getByLabel(Language.usernameLabel).fill(constants.username);
1011
await page.getByLabel(Language.emailLabel).fill(constants.email);
1112
await page.getByLabel(Language.passwordLabel).fill(constants.password);
@@ -15,4 +16,15 @@ test("setup first user", async ({ page }) => {
1516
await page.context().storageState({ path: storageState });
1617

1718
await page.getByTestId("button-select-template").isVisible();
19+
20+
// Setup license
21+
if (constants.enterpriseLicense) {
22+
await page.goto("/deployment/licenses", { waitUntil: "domcontentloaded" });
23+
24+
await page.getByText("Add a license").click();
25+
await page.getByRole("textbox").fill(constants.enterpriseLicense);
26+
await page.getByText("Upload License").click();
27+
28+
await page.getByText("You have successfully added a license").isVisible();
29+
}
1830
});

site/e2e/helpers.ts

+16-17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type BrowserContext, expect, type Page } from "@playwright/test";
1+
import { type BrowserContext, expect, type Page, test } from "@playwright/test";
22
import axios from "axios";
33
import { type ChildProcess, exec, spawn } from "child_process";
44
import { randomUUID } from "crypto";
@@ -12,7 +12,13 @@ import type {
1212
UpdateTemplateMeta,
1313
} from "api/typesGenerated";
1414
import { TarWriter } from "utils/tar";
15-
import { agentPProfPort, coderPort, prometheusPort } from "./constants";
15+
import {
16+
agentPProfPort,
17+
coderMain,
18+
coderPort,
19+
enterpriseLicense,
20+
prometheusPort,
21+
} from "./constants";
1622
import {
1723
Agent,
1824
type App,
@@ -25,6 +31,11 @@ import {
2531
type RichParameter,
2632
} from "./provisionerGenerated";
2733

34+
// requiresEnterpriseLicense will skip the test if we're not running with an enterprise license
35+
export function requiresEnterpriseLicense() {
36+
test.skip(!enterpriseLicense);
37+
}
38+
2839
// createWorkspace creates a workspace for a template.
2940
// It does not wait for it to be running, but it does navigate to the page.
3041
export const createWorkspace = async (
@@ -147,7 +158,7 @@ export const sshIntoWorkspace = async (
147158
binaryArgs: string[] = [],
148159
): Promise<ssh.Client> => {
149160
if (binaryPath === "go") {
150-
binaryArgs = ["run", coderMainPath()];
161+
binaryArgs = ["run", coderMain];
151162
}
152163
const sessionToken = await findSessionToken(page);
153164
return new Promise<ssh.Client>((resolve, reject) => {
@@ -229,7 +240,7 @@ export const startAgent = async (
229240
page: Page,
230241
token: string,
231242
): Promise<ChildProcess> => {
232-
return startAgentWithCommand(page, token, "go", "run", coderMainPath());
243+
return startAgentWithCommand(page, token, "go", "run", coderMain);
233244
};
234245

235246
// downloadCoderVersion downloads the version provided into a temporary dir and
@@ -358,18 +369,6 @@ const waitUntilUrlIsNotResponding = async (url: string) => {
358369
);
359370
};
360371

361-
const coderMainPath = (): string => {
362-
return path.join(
363-
__dirname,
364-
"..",
365-
"..",
366-
"enterprise",
367-
"cmd",
368-
"coder",
369-
"main.go",
370-
);
371-
};
372-
373372
// Allows users to more easily define properties they want for agents and resources!
374373
type RecursivePartial<T> = {
375374
[P in keyof T]?: T[P] extends (infer U)[]
@@ -686,7 +685,7 @@ export const updateTemplate = async (
686685
"go",
687686
[
688687
"run",
689-
coderMainPath(),
688+
coderMain,
690689
"templates",
691690
"push",
692691
"--test.provisioner",

site/e2e/playwright.config.ts

+5-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { defineConfig } from "@playwright/test";
2-
import path from "path";
3-
import { coderPort, coderdPProfPort, gitAuth } from "./constants";
2+
import * as path from "path";
3+
import { coderMain, coderPort, coderdPProfPort, gitAuth } from "./constants";
44

55
export const wsEndpoint = process.env.CODER_E2E_WS_ENDPOINT;
66

7-
const coderMain = path.join(__dirname, "../../enterprise/cmd/coder");
8-
97
// This is where auth cookies are stored!
108
export const storageState = path.join(__dirname, ".auth.json");
119

@@ -16,16 +14,14 @@ const localURL = (port: number, path: string): string => {
1614
export default defineConfig({
1715
projects: [
1816
{
19-
name: "setup",
17+
name: "testsSetup",
2018
testMatch: /global.setup\.ts/,
2119
},
2220
{
2321
name: "tests",
2422
testMatch: /.*\.spec\.ts/,
25-
dependencies: ["setup"],
26-
use: {
27-
storageState: storageState,
28-
},
23+
dependencies: ["testsSetup"],
24+
use: { storageState },
2925
timeout: 60_000,
3026
},
3127
],

site/e2e/tests/updateTemplate.spec.ts

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import { test } from "@playwright/test";
2-
import { createTemplate, updateTemplateSettings } from "../helpers";
1+
import { expect, test } from "@playwright/test";
2+
import {
3+
createTemplate,
4+
requiresEnterpriseLicense,
5+
updateTemplateSettings,
6+
} from "../helpers";
37

48
test("template update with new name redirects on successful submit", async ({
59
page,
@@ -10,3 +14,24 @@ test("template update with new name redirects on successful submit", async ({
1014
name: "new-name",
1115
});
1216
});
17+
18+
test("require latest version", async ({ page }) => {
19+
requiresEnterpriseLicense();
20+
21+
const templateName = await createTemplate(page);
22+
23+
await page.goto(`/templates/${templateName}/settings`, {
24+
waitUntil: "domcontentloaded",
25+
});
26+
await expect(page).toHaveURL(`/templates/${templateName}/settings`);
27+
let checkbox = await page.waitForSelector("#require_active_version");
28+
await checkbox.click();
29+
await page.getByTestId("form-submit").click();
30+
31+
await page.goto(`/templates/${templateName}/settings`, {
32+
waitUntil: "domcontentloaded",
33+
});
34+
checkbox = await page.waitForSelector("#require_active_version");
35+
await checkbox.scrollIntoViewIfNeeded();
36+
expect(await checkbox.isChecked()).toBe(true);
37+
});

site/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
},
9696
"devDependencies": {
9797
"@octokit/types": "12.3.0",
98-
"@playwright/test": "1.39.0",
98+
"@playwright/test": "1.42.1",
9999
"@storybook/addon-actions": "7.6.11",
100100
"@storybook/addon-essentials": "7.6.11",
101101
"@storybook/addon-interactions": "7.6.11",

site/pnpm-lock.yaml

+10-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)