diff --git a/site/e2e/constants.ts b/site/e2e/constants.ts index 4ec0048e69..4fcada0e6d 100644 --- a/site/e2e/constants.ts +++ b/site/e2e/constants.ts @@ -24,16 +24,22 @@ export const users = { password: defaultPassword, email: "admin@coder.com", }, + templateAdmin: { + username: "template-admin", + password: defaultPassword, + email: "templateadmin@coder.com", + roles: ["Template Admin"], + }, auditor: { username: "auditor", password: defaultPassword, email: "auditor@coder.com", roles: ["Template Admin", "Auditor"], }, - user: { - username: "user", + member: { + username: "member", password: defaultPassword, - email: "user@coder.com", + email: "member@coder.com", }, } satisfies Record< string, diff --git a/site/e2e/helpers.ts b/site/e2e/helpers.ts index a2f55ad2c8..5692909355 100644 --- a/site/e2e/helpers.ts +++ b/site/e2e/helpers.ts @@ -150,7 +150,6 @@ export const createWorkspace = async ( await page.getByRole("button", { name: /create workspace/i }).click(); const user = currentUser(page); - await expectUrl(page).toHavePathName(`/@${user.username}/${name}`); await page.waitForSelector("[data-testid='build-status'] >> text=Running", { @@ -165,12 +164,10 @@ export const verifyParameters = async ( richParameters: RichParameter[], expectedBuildParameters: WorkspaceBuildParameter[], ) => { - await page.goto(`/@admin/${workspaceName}/settings/parameters`, { + const user = currentUser(page); + await page.goto(`/@${user.username}/${workspaceName}/settings/parameters`, { waitUntil: "domcontentloaded", }); - await expectUrl(page).toHavePathName( - `/@admin/${workspaceName}/settings/parameters`, - ); for (const buildParameter of expectedBuildParameters) { const richParameter = richParameters.find( @@ -356,10 +353,10 @@ export const sshIntoWorkspace = async ( }; export const stopWorkspace = async (page: Page, workspaceName: string) => { - await page.goto(`/@admin/${workspaceName}`, { + const user = currentUser(page); + await page.goto(`/@${user.username}/${workspaceName}`, { waitUntil: "domcontentloaded", }); - await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`); await page.getByTestId("workspace-stop-button").click(); @@ -375,10 +372,10 @@ export const buildWorkspaceWithParameters = async ( buildParameters: WorkspaceBuildParameter[] = [], confirm = false, ) => { - await page.goto(`/@admin/${workspaceName}`, { + const user = currentUser(page); + await page.goto(`/@${user.username}/${workspaceName}`, { waitUntil: "domcontentloaded", }); - await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`); await page.getByTestId("build-parameters-button").click(); @@ -993,10 +990,10 @@ export const updateWorkspace = async ( richParameters: RichParameter[] = [], buildParameters: WorkspaceBuildParameter[] = [], ) => { - await page.goto(`/@admin/${workspaceName}`, { + const user = currentUser(page); + await page.goto(`/@${user.username}/${workspaceName}`, { waitUntil: "domcontentloaded", }); - await expectUrl(page).toHavePathName(`/@admin/${workspaceName}`); await page.getByTestId("workspace-update-button").click(); await page.getByTestId("confirm-button").click(); @@ -1015,12 +1012,10 @@ export const updateWorkspaceParameters = async ( richParameters: RichParameter[] = [], buildParameters: WorkspaceBuildParameter[] = [], ) => { - await page.goto(`/@admin/${workspaceName}/settings/parameters`, { + const user = currentUser(page); + await page.goto(`/@${user.username}/${workspaceName}/settings/parameters`, { waitUntil: "domcontentloaded", }); - await expectUrl(page).toHavePathName( - `/@admin/${workspaceName}/settings/parameters`, - ); await fillParameters(page, richParameters, buildParameters); await page.getByRole("button", { name: /submit and restart/i }).click(); @@ -1044,11 +1039,14 @@ export async function openTerminalWindow( // Specify that the shell should be `bash`, to prevent inheriting a shell that // isn't POSIX compatible, such as Fish. + const user = currentUser(page); const commandQuery = `?command=${encodeURIComponent("/usr/bin/env bash")}`; await expectUrl(terminal).toHavePathName( - `/@admin/${workspaceName}.${agentName}/terminal`, + `/@${user.username}/${workspaceName}.${agentName}/terminal`, + ); + await terminal.goto( + `/@${user.username}/${workspaceName}.${agentName}/terminal${commandQuery}`, ); - await terminal.goto(`/@admin/${workspaceName}.dev/terminal${commandQuery}`); return terminal; } @@ -1100,7 +1098,7 @@ export async function createUser( // Give them a role await addedRow.getByLabel("Edit user roles").click(); for (const role of roles) { - await page.getByText(role, { exact: true }).click(); + await page.getByRole("group").getByText(role, { exact: true }).click(); } await page.mouse.click(10, 10); // close the popover by clicking outside of it diff --git a/site/e2e/tests/workspaces/autoCreateWorkspace.spec.ts b/site/e2e/tests/workspaces/autoCreateWorkspace.spec.ts index 4bf9b26bb2..a6ec00958a 100644 --- a/site/e2e/tests/workspaces/autoCreateWorkspace.spec.ts +++ b/site/e2e/tests/workspaces/autoCreateWorkspace.spec.ts @@ -16,7 +16,7 @@ let template!: string; test.beforeAll(async ({ browser }) => { const page = await (await browser.newContext()).newPage(); - await login(page); + await login(page, users.templateAdmin); const richParameters: RichParameter[] = [ { ...emptyParameter, name: "repo", type: "string" }, @@ -29,7 +29,7 @@ test.beforeAll(async ({ browser }) => { test.beforeEach(async ({ page }) => { beforeCoderTest(page); - await login(page, users.user); + await login(page, users.member); }); test("create workspace in auto mode", async ({ page }) => { @@ -40,7 +40,7 @@ test("create workspace in auto mode", async ({ page }) => { waitUntil: "domcontentloaded", }, ); - await expect(page).toHaveTitle(`${users.user.username}/${name} - Coder`); + await expect(page).toHaveTitle(`${users.member.username}/${name} - Coder`); }); test("use an existing workspace that matches the `match` parameter instead of creating a new one", async ({ @@ -54,7 +54,7 @@ test("use an existing workspace that matches the `match` parameter instead of cr }, ); await expect(page).toHaveTitle( - `${users.user.username}/${prevWorkspace} - Coder`, + `${users.member.username}/${prevWorkspace} - Coder`, ); }); diff --git a/site/e2e/tests/workspaces/createWorkspace.spec.ts b/site/e2e/tests/workspaces/createWorkspace.spec.ts index ce1898a310..49b832d285 100644 --- a/site/e2e/tests/workspaces/createWorkspace.spec.ts +++ b/site/e2e/tests/workspaces/createWorkspace.spec.ts @@ -1,4 +1,5 @@ import { expect, test } from "@playwright/test"; +import { users } from "../../constants"; import { StarterTemplates, createTemplate, @@ -26,27 +27,20 @@ test.describe.configure({ mode: "parallel" }); test.beforeEach(async ({ page }) => { beforeCoderTest(page); - await login(page); }); test("create workspace", async ({ page }) => { + await login(page, users.templateAdmin); const template = await createTemplate(page, { - apply: [ - { - apply: { - resources: [ - { - name: "example", - }, - ], - }, - }, - ], + apply: [{ apply: { resources: [{ name: "example" }] } }], }); + + await login(page, users.member); await createWorkspace(page, template); }); test("create workspace with default immutable parameters", async ({ page }) => { + await login(page, users.templateAdmin); const richParameters: RichParameter[] = [ secondParameter, fourthParameter, @@ -56,6 +50,8 @@ test("create workspace with default immutable parameters", async ({ page }) => { page, echoResponsesWithParameters(richParameters), ); + + await login(page, users.member); const workspaceName = await createWorkspace(page, template); await verifyParameters(page, workspaceName, richParameters, [ { name: secondParameter.name, value: secondParameter.defaultValue }, @@ -65,11 +61,14 @@ test("create workspace with default immutable parameters", async ({ page }) => { }); test("create workspace with default mutable parameters", async ({ page }) => { + await login(page, users.templateAdmin); const richParameters: RichParameter[] = [firstParameter, thirdParameter]; const template = await createTemplate( page, echoResponsesWithParameters(richParameters), ); + + await login(page, users.member); const workspaceName = await createWorkspace(page, template); await verifyParameters(page, workspaceName, richParameters, [ { name: firstParameter.name, value: firstParameter.defaultValue }, @@ -80,6 +79,7 @@ test("create workspace with default mutable parameters", async ({ page }) => { test("create workspace with default and required parameters", async ({ page, }) => { + await login(page, users.templateAdmin); const richParameters: RichParameter[] = [ secondParameter, fourthParameter, @@ -94,6 +94,8 @@ test("create workspace with default and required parameters", async ({ page, echoResponsesWithParameters(richParameters), ); + + await login(page, users.member); const workspaceName = await createWorkspace(page, template, { richParameters, buildParameters, @@ -108,6 +110,7 @@ test("create workspace with default and required parameters", async ({ }); test("create workspace and overwrite default parameters", async ({ page }) => { + await login(page, users.templateAdmin); // We use randParamName to prevent the new values from corrupting user_history // and thus affecting other tests. const richParameters: RichParameter[] = [ @@ -124,6 +127,7 @@ test("create workspace and overwrite default parameters", async ({ page }) => { echoResponsesWithParameters(richParameters), ); + await login(page, users.member); const workspaceName = await createWorkspace(page, template, { richParameters, buildParameters, @@ -132,6 +136,7 @@ test("create workspace and overwrite default parameters", async ({ page }) => { }); test("create workspace with disable_param search params", async ({ page }) => { + await login(page, users.templateAdmin); const richParameters: RichParameter[] = [ firstParameter, // mutable secondParameter, //immutable @@ -142,6 +147,7 @@ test("create workspace with disable_param search params", async ({ page }) => { echoResponsesWithParameters(richParameters), ); + await login(page, users.member); await page.goto( `/templates/${templateName}/workspace?disable_params=first_parameter,second_parameter`, { @@ -157,8 +163,11 @@ test("create workspace with disable_param search params", async ({ page }) => { // the tests are over. test.skip("create docker workspace", async ({ context, page }) => { requireTerraformProvisioner(); + + await login(page, users.templateAdmin); const template = await createTemplate(page, StarterTemplates.STARTER_DOCKER); + await login(page, users.member); const workspaceName = await createWorkspace(page, template); // The workspace agents must be ready before we try to interact with the workspace. @@ -184,8 +193,6 @@ test.skip("create docker workspace", async ({ context, page }) => { ); await terminal.waitForSelector( `//textarea[contains(@class,"xterm-helper-textarea")]`, - { - state: "visible", - }, + { state: "visible" }, ); }); diff --git a/site/e2e/tests/workspaces/restartWorkspace.spec.ts b/site/e2e/tests/workspaces/restartWorkspace.spec.ts index b65fa95208..444ff891f0 100644 --- a/site/e2e/tests/workspaces/restartWorkspace.spec.ts +++ b/site/e2e/tests/workspaces/restartWorkspace.spec.ts @@ -1,4 +1,5 @@ import { test } from "@playwright/test"; +import { users } from "../../constants"; import { buildWorkspaceWithParameters, createTemplate, @@ -13,15 +14,17 @@ import type { RichParameter } from "../../provisionerGenerated"; test.beforeEach(async ({ page }) => { beforeCoderTest(page); - await login(page); }); test("restart workspace with ephemeral parameters", async ({ page }) => { + await login(page, users.templateAdmin); const richParameters: RichParameter[] = [firstBuildOption, secondBuildOption]; const template = await createTemplate( page, echoResponsesWithParameters(richParameters), ); + + await login(page, users.member); const workspaceName = await createWorkspace(page, template); // Verify that build options are default (not selected). diff --git a/site/e2e/tests/workspaces/startWorkspace.spec.ts b/site/e2e/tests/workspaces/startWorkspace.spec.ts index d22c8f4f34..90fac44004 100644 --- a/site/e2e/tests/workspaces/startWorkspace.spec.ts +++ b/site/e2e/tests/workspaces/startWorkspace.spec.ts @@ -1,4 +1,5 @@ import { test } from "@playwright/test"; +import { users } from "../../constants"; import { buildWorkspaceWithParameters, createTemplate, @@ -14,15 +15,17 @@ import type { RichParameter } from "../../provisionerGenerated"; test.beforeEach(async ({ page }) => { beforeCoderTest(page); - await login(page); }); test("start workspace with ephemeral parameters", async ({ page }) => { + await login(page, users.templateAdmin); const richParameters: RichParameter[] = [firstBuildOption, secondBuildOption]; const template = await createTemplate( page, echoResponsesWithParameters(richParameters), ); + + await login(page, users.member); const workspaceName = await createWorkspace(page, template); // Verify that build options are default (not selected). diff --git a/site/e2e/tests/workspaces/updateWorkspace.spec.ts b/site/e2e/tests/workspaces/updateWorkspace.spec.ts index 1db6231646..48c341eb63 100644 --- a/site/e2e/tests/workspaces/updateWorkspace.spec.ts +++ b/site/e2e/tests/workspaces/updateWorkspace.spec.ts @@ -1,4 +1,5 @@ import { test } from "@playwright/test"; +import { users } from "../../constants"; import { createTemplate, createWorkspace, @@ -21,18 +22,19 @@ import type { RichParameter } from "../../provisionerGenerated"; test.beforeEach(async ({ page }) => { beforeCoderTest(page); - await login(page); }); test("update workspace, new optional, immutable parameter added", async ({ page, }) => { + await login(page, users.templateAdmin); const richParameters: RichParameter[] = [firstParameter, secondParameter]; const template = await createTemplate( page, echoResponsesWithParameters(richParameters), ); + await login(page, users.member); const workspaceName = await createWorkspace(page, template); // Verify that parameter values are default. @@ -42,6 +44,7 @@ test("update workspace, new optional, immutable parameter added", async ({ ]); // Push updated template. + await login(page, users.templateAdmin); const updatedRichParameters = [...richParameters, fifthParameter]; await updateTemplate( page, @@ -51,6 +54,7 @@ test("update workspace, new optional, immutable parameter added", async ({ ); // Now, update the workspace, and select the value for immutable parameter. + await login(page, users.member); await updateWorkspace(page, workspaceName, updatedRichParameters, [ { name: fifthParameter.name, value: fifthParameter.options[0].value }, ]); @@ -66,12 +70,14 @@ test("update workspace, new optional, immutable parameter added", async ({ test("update workspace, new required, mutable parameter added", async ({ page, }) => { + await login(page, users.templateAdmin); const richParameters: RichParameter[] = [firstParameter, secondParameter]; const template = await createTemplate( page, echoResponsesWithParameters(richParameters), ); + await login(page, users.member); const workspaceName = await createWorkspace(page, template); // Verify that parameter values are default. @@ -81,6 +87,7 @@ test("update workspace, new required, mutable parameter added", async ({ ]); // Push updated template. + await login(page, users.templateAdmin); const updatedRichParameters = [...richParameters, sixthParameter]; await updateTemplate( page, @@ -90,6 +97,7 @@ test("update workspace, new required, mutable parameter added", async ({ ); // Now, update the workspace, and provide the parameter value. + await login(page, users.member); const buildParameters = [{ name: sixthParameter.name, value: "99" }]; await updateWorkspace( page, @@ -107,12 +115,14 @@ test("update workspace, new required, mutable parameter added", async ({ }); test("update workspace with ephemeral parameter enabled", async ({ page }) => { + await login(page, users.templateAdmin); const richParameters: RichParameter[] = [firstParameter, secondBuildOption]; const template = await createTemplate( page, echoResponsesWithParameters(richParameters), ); + await login(page, users.member); const workspaceName = await createWorkspace(page, template); // Verify that parameter values are default.