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

This commit is contained in:
Marcin Tojek
2023-08-25 14:50:38 +02:00
committed by GitHub
parent aed891b4ff
commit d7a788d89d
5 changed files with 219 additions and 52 deletions

View File

@ -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
}
@ -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> => {
@ -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)
}
}
}

View File

@ -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",
@ -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,
}
@ -56,7 +53,6 @@ export const thirdParameter: RichParameter = {
name: "third_parameter",
type: "string",
options: [],
description: "This is third parameter.",
defaultValue: "",
mutable: true,
@ -69,10 +65,8 @@ export const fourthParameter: RichParameter = {
name: "fourth_parameter",
type: "bool",
options: [],
description: "This is fourth parameter.",
defaultValue: "true",
icon: "",
order: 3,
}
@ -105,7 +99,6 @@ export const fifthParameter: RichParameter = {
],
description: "This is fifth parameter.",
defaultValue: "def",
icon: "",
order: 3,
}
@ -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,
@ -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,
}

View File

@ -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 },
])
})

View File

@ -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 },
])
})

View File

@ -94,6 +94,7 @@ export const StopButton: FC<WorkspaceAction> = ({ handleAction, loading }) => {
loadingPosition="start"
startIcon={<CropSquareIcon />}
onClick={handleAction}
data-testid="workspace-stop-button"
>
Stop
</LoadingButton>