Skip to content

test(site): e2e: restart workspace with ephemeral parameters #9304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 97 additions & 43 deletions site/e2e/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,52 +34,16 @@ export const createWorkspace = async (
const name = randomName()
await page.getByLabel("name").fill(name)

for (const buildParameter of buildParameters) {
const richParameter = richParameters.find(
(richParam) => richParam.name === buildParameter.name,
)
if (!richParameter) {
throw new Error(
"build parameter is expected to be present in rich parameter schema",
)
}

const parameterLabel = await page.waitForSelector(
"[data-testid='parameter-field-" + richParameter.name + "']",
{ state: "visible" },
)

if (richParameter.type === "bool") {
const parameterField = await parameterLabel.waitForSelector(
"[data-testid='parameter-field-bool'] .MuiRadio-root input[value='" +
buildParameter.value +
"']",
)
await parameterField.check()
} else if (richParameter.options.length > 0) {
const parameterField = await parameterLabel.waitForSelector(
"[data-testid='parameter-field-options'] .MuiRadio-root input[value='" +
buildParameter.value +
"']",
)
await parameterField.check()
} else if (richParameter.type === "list(string)") {
throw new Error("not implemented yet") // FIXME
} else {
// text or number
const parameterField = await parameterLabel.waitForSelector(
"[data-testid='parameter-field-text'] input",
)
await parameterField.fill(buildParameter.value)
}
}

await fillParameters(page, richParameters, buildParameters)
await page.getByTestId("form-submit").click()

await expect(page).toHaveURL("/@admin/" + name)
await page.waitForSelector("[data-testid='build-status']", {
state: "visible",
})
await page.waitForSelector(
"span[data-testid='build-status'] >> text=Running",
{
state: "visible",
},
)
return name
}

Expand Down Expand Up @@ -213,6 +177,50 @@ export const sshIntoWorkspace = async (
})
}

export const stopWorkspace = async (page: Page, workspaceName: string) => {
await page.goto("/@admin/" + workspaceName, {
waitUntil: "domcontentloaded",
})
await expect(page).toHaveURL("/@admin/" + workspaceName)

await page.getByTestId("workspace-stop-button").click()

await page.waitForSelector(
"span[data-testid='build-status'] >> text=Stopped",
{
state: "visible",
},
)
}

export const buildWorkspaceWithParameters = async (
page: Page,
workspaceName: string,
richParameters: RichParameter[] = [],
buildParameters: WorkspaceBuildParameter[] = [],
confirm: boolean = false,
) => {
await page.goto("/@admin/" + workspaceName, {
waitUntil: "domcontentloaded",
})
await expect(page).toHaveURL("/@admin/" + workspaceName)

await page.getByTestId("build-parameters-button").click()

await fillParameters(page, richParameters, buildParameters)
await page.getByTestId("build-parameters-submit").click()
if (confirm) {
await page.getByTestId("confirm-button").click()
}

await page.waitForSelector(
"span[data-testid='build-status'] >> text=Running",
{
state: "visible",
},
)
}

// startAgent runs the coder agent with the provided token.
// It awaits the agent to be ready before returning.
export const startAgent = async (page: Page, token: string): Promise<void> => {
Expand Down Expand Up @@ -561,3 +569,49 @@ export const echoResponsesWithParameters = (
],
}
}

export const fillParameters = async (
page: Page,
richParameters: RichParameter[] = [],
buildParameters: WorkspaceBuildParameter[] = [],
) => {
for (const buildParameter of buildParameters) {
const richParameter = richParameters.find(
(richParam) => richParam.name === buildParameter.name,
)
if (!richParameter) {
throw new Error(
"build parameter is expected to be present in rich parameter schema",
)
}

const parameterLabel = await page.waitForSelector(
"[data-testid='parameter-field-" + richParameter.name + "']",
{ state: "visible" },
)

if (richParameter.type === "bool") {
const parameterField = await parameterLabel.waitForSelector(
"[data-testid='parameter-field-bool'] .MuiRadio-root input[value='" +
buildParameter.value +
"']",
)
await parameterField.check()
} else if (richParameter.options.length > 0) {
const parameterField = await parameterLabel.waitForSelector(
"[data-testid='parameter-field-options'] .MuiRadio-root input[value='" +
buildParameter.value +
"']",
)
await parameterField.check()
} else if (richParameter.type === "list(string)") {
throw new Error("not implemented yet") // FIXME
} else {
// text or number
const parameterField = await parameterLabel.waitForSelector(
"[data-testid='parameter-field-text'] input",
)
await parameterField.fill(buildParameter.value)
}
}
}
36 changes: 27 additions & 9 deletions site/e2e/parameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export const firstParameter: RichParameter = {
name: "first_parameter",
displayName: "First parameter",
type: "number",
options: [],
description: "This is first parameter.",
icon: "/emojis/1f310.png",
defaultValue: "123",
Expand All @@ -43,10 +42,8 @@ export const secondParameter: RichParameter = {
name: "second_parameter",
displayName: "Second parameter",
type: "string",
options: [],
description: "This is second parameter.",
defaultValue: "abc",
icon: "",
order: 2,
}

Expand All @@ -56,7 +53,6 @@ export const thirdParameter: RichParameter = {

name: "third_parameter",
type: "string",
options: [],
description: "This is third parameter.",
defaultValue: "",
mutable: true,
Expand All @@ -69,10 +65,8 @@ export const fourthParameter: RichParameter = {

name: "fourth_parameter",
type: "bool",
options: [],
description: "This is fourth parameter.",
defaultValue: "true",
icon: "",
order: 3,
}

Expand Down Expand Up @@ -105,7 +99,6 @@ export const fifthParameter: RichParameter = {
],
description: "This is fifth parameter.",
defaultValue: "def",
icon: "",
order: 3,
}

Expand All @@ -116,7 +109,6 @@ export const sixthParameter: RichParameter = {
name: "sixth_parameter",
displayName: "Sixth parameter",
type: "number",
options: [],
description: "This is sixth parameter.",
icon: "/emojis/1f310.png",
required: true,
Expand All @@ -131,8 +123,34 @@ export const seventhParameter: RichParameter = {
name: "seventh_parameter",
displayName: "Seventh parameter",
type: "string",
options: [],
description: "This is seventh parameter.",
required: true,
order: 1,
}

// Build options

export const firstBuildOption: RichParameter = {
...emptyParameter,

name: "first_build_option",
displayName: "First build option",
type: "string",
description: "This is first build option.",
icon: "/emojis/1f310.png",
defaultValue: "ABCDEF",
mutable: true,
ephemeral: true,
}

export const secondBuildOption: RichParameter = {
...emptyParameter,

name: "second_build_option",
displayName: "Second build option",
type: "bool",
description: "This is second build option.",
defaultValue: "false",
mutable: true,
ephemeral: true,
}
45 changes: 45 additions & 0 deletions site/e2e/tests/restartWorkspace.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { test } from "@playwright/test"
import {
buildWorkspaceWithParameters,
createTemplate,
createWorkspace,
echoResponsesWithParameters,
verifyParameters,
} from "../helpers"

import { firstBuildOption, secondBuildOption } from "../parameters"
import { RichParameter } from "../provisionerGenerated"

test("restart workspace with ephemeral parameters", async ({ page }) => {
const richParameters: RichParameter[] = [firstBuildOption, secondBuildOption]
const template = await createTemplate(
page,
echoResponsesWithParameters(richParameters),
)
const workspaceName = await createWorkspace(page, template)

// Verify that build options are default (not selected).
await verifyParameters(page, workspaceName, richParameters, [
{ name: firstBuildOption.name, value: firstBuildOption.defaultValue },
{ name: secondBuildOption.name, value: secondBuildOption.defaultValue },
])

// Now, restart the workspace with ephemeral parameters selected.
const buildParameters = [
{ name: firstBuildOption.name, value: "AAAAA" },
{ name: secondBuildOption.name, value: "true" },
]
await buildWorkspaceWithParameters(
page,
workspaceName,
richParameters,
buildParameters,
true,
)

// Verify that build options are default (not selected).
await verifyParameters(page, workspaceName, richParameters, [
{ name: firstBuildOption.name, value: firstBuildOption.defaultValue },
{ name: secondBuildOption.name, value: secondBuildOption.defaultValue },
])
})
49 changes: 49 additions & 0 deletions site/e2e/tests/startWorkspace.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { test } from "@playwright/test"
import {
buildWorkspaceWithParameters,
createTemplate,
createWorkspace,
echoResponsesWithParameters,
stopWorkspace,
verifyParameters,
} from "../helpers"

import { firstBuildOption, secondBuildOption } from "../parameters"
import { RichParameter } from "../provisionerGenerated"

test("start workspace with ephemeral parameters", async ({ page }) => {
const richParameters: RichParameter[] = [firstBuildOption, secondBuildOption]
const template = await createTemplate(
page,
echoResponsesWithParameters(richParameters),
)
const workspaceName = await createWorkspace(page, template)

// Verify that build options are default (not selected).
await verifyParameters(page, workspaceName, richParameters, [
{ name: firstBuildOption.name, value: firstBuildOption.defaultValue },
{ name: secondBuildOption.name, value: secondBuildOption.defaultValue },
])

// Stop the workspace
await stopWorkspace(page, workspaceName)

// Now, start the workspace with ephemeral parameters selected.
const buildParameters = [
{ name: firstBuildOption.name, value: "AAAAA" },
{ name: secondBuildOption.name, value: "true" },
]

await buildWorkspaceWithParameters(
page,
workspaceName,
richParameters,
buildParameters,
)

// Verify that build options are default (not selected).
await verifyParameters(page, workspaceName, richParameters, [
{ name: firstBuildOption.name, value: firstBuildOption.defaultValue },
{ name: secondBuildOption.name, value: secondBuildOption.defaultValue },
])
})
1 change: 1 addition & 0 deletions site/src/components/WorkspaceActions/Buttons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export const StopButton: FC<WorkspaceAction> = ({ handleAction, loading }) => {
loadingPosition="start"
startIcon={<CropSquareIcon />}
onClick={handleAction}
data-testid="workspace-stop-button"
>
Stop
</LoadingButton>
Expand Down