Skip to content

test(site): e2e: create workspace with rich parameters #9185

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 15 commits into from
Aug 22, 2023
133 changes: 132 additions & 1 deletion site/e2e/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,135 @@ import {
Provision_Complete,
Provision_Response,
Resource,
RichParameter,
} from "./provisionerGenerated"
import { port } from "./playwright.config"
import * as ssh from "ssh2"
import { Duplex } from "stream"
import { WorkspaceBuildParameter } from "api/typesGenerated"

// 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 (
page: Page,
templateName: string,
richParameters: RichParameter[] = [],
buildParameters: WorkspaceBuildParameter[] = [],
): Promise<string> => {
await page.goto("/templates/" + templateName + "/workspace", {
waitUntil: "networkidle",
})
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 page.getByTestId("form-submit").click()

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

export const verifyParameters = async (
page: Page,
workspaceName: string,
richParameters: RichParameter[],
expectedBuildParameters: WorkspaceBuildParameter[],
) => {
await page.goto("/@admin/" + workspaceName + "/settings/parameters", {
waitUntil: "networkidle",
})
await expect(page).toHaveURL(
"/@admin/" + workspaceName + "/settings/parameters",
)

for (const buildParameter of expectedBuildParameters) {
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" },
)

const muiDisabled = richParameter.mutable ? "" : ".Mui-disabled"

if (richParameter.type === "bool") {
const parameterField = await parameterLabel.waitForSelector(
"[data-testid='parameter-field-bool'] .MuiRadio-root.Mui-checked" +
muiDisabled +
" input",
)
const value = await parameterField.inputValue()
expect(value).toEqual(buildParameter.value)
} else if (richParameter.options.length > 0) {
const parameterField = await parameterLabel.waitForSelector(
"[data-testid='parameter-field-options'] .MuiRadio-root.Mui-checked" +
muiDisabled +
" input",
)
const value = await parameterField.inputValue()
expect(value).toEqual(buildParameter.value)
} 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" + muiDisabled,
)
const value = await parameterField.inputValue()
expect(value).toEqual(buildParameter.value)
}
}
}

// createTemplate navigates to the /templates/new page and uploads a template
// with the resources provided in the responses argument.
export const createTemplate = async (
Expand Down Expand Up @@ -401,3 +507,28 @@ const findSessionToken = async (page: Page): Promise<string> => {
}
return sessionCookie.value
}

export const echoResponsesWithParameters = (
richParameters: RichParameter[],
): EchoProvisionerResponses => {
return {
plan: [
{
complete: {
parameters: richParameters,
},
},
],
apply: [
{
complete: {
resources: [
{
name: "example",
},
],
},
},
],
}
}
138 changes: 138 additions & 0 deletions site/e2e/parameters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { RichParameter } from "./provisionerGenerated"

// Rich parameters

const emptyParameter: RichParameter = {
name: "",
description: "",
type: "",
mutable: false,
defaultValue: "",
icon: "",
options: [],
validationRegex: "",
validationError: "",
validationMin: undefined,
validationMax: undefined,
validationMonotonic: "",
required: false,
displayName: "",
order: 0,
ephemeral: false,
}

// firstParameter is mutable string with a default value (parameter value not required).
export const firstParameter: RichParameter = {
...emptyParameter,

name: "first_parameter",
displayName: "First parameter",
type: "number",
options: [],
description: "This is first parameter.",
icon: "/emojis/1f310.png",
defaultValue: "123",
mutable: true,
order: 1,
}

// secondParameter is immutable string with a default value (parameter value not required).
export const secondParameter: RichParameter = {
...emptyParameter,

name: "second_parameter",
displayName: "Second parameter",
type: "string",
options: [],
description: "This is second parameter.",
defaultValue: "abc",
icon: "",
order: 2,
}

// thirdParameter is mutable string with an empty default value (parameter value not required).
export const thirdParameter: RichParameter = {
...emptyParameter,

name: "third_parameter",
type: "string",
options: [],
description: "This is third parameter.",
defaultValue: "",
mutable: true,
order: 3,
}

// fourthParameter is immutable boolean with a default "true" value (parameter value not required).
export const fourthParameter: RichParameter = {
...emptyParameter,

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

// fifthParameter is immutable "string with options", with a default option selected (parameter value not required).
export const fifthParameter: RichParameter = {
...emptyParameter,

name: "fifth_parameter",
displayName: "Fifth parameter",
type: "string",
options: [
{
name: "ABC",
description: "This is ABC",
value: "abc",
icon: "",
},
{
name: "DEF",
description: "This is DEF",
value: "def",
icon: "",
},
{
name: "GHI",
description: "This is GHI",
value: "ghi",
icon: "",
},
],
description: "This is fifth parameter.",
defaultValue: "def",
icon: "",
order: 3,
}

// sixthParameter is mutable string without a default value (parameter value is required).
export const sixthParameter: RichParameter = {
...emptyParameter,

name: "sixth_parameter",
displayName: "Sixth parameter",
type: "number",
options: [],
description: "This is sixth parameter.",
icon: "/emojis/1f310.png",
required: true,
mutable: true,
order: 1,
}

// seventhParameter is immutable string without a default value (parameter value is required).
export const seventhParameter: RichParameter = {
...emptyParameter,

name: "seventh_parameter",
displayName: "Seventh parameter",
type: "string",
options: [],
description: "This is seventh parameter.",
required: true,
order: 1,
}
Loading