Skip to content

Commit 956cbe7

Browse files
authored
chore: remove classic parameters frontend code (#20710)
1 parent 4863812 commit 956cbe7

24 files changed

+1538
-3357
lines changed

site/e2e/helpers.ts

Lines changed: 118 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -183,34 +183,37 @@ export const verifyParameters = async (
183183
);
184184
}
185185

186-
const parameterLabel = await page.waitForSelector(
187-
`[data-testid='parameter-field-${richParameter.name}']`,
188-
{ state: "visible" },
186+
const parameterLabel = page.getByTestId(
187+
`parameter-field-${richParameter.displayName}`,
189188
);
189+
await expect(parameterLabel).toBeVisible();
190190

191-
const muiDisabled = richParameter.mutable ? "" : ".Mui-disabled";
191+
if (richParameter.options.length > 0) {
192+
const parameterValue = parameterLabel.getByLabel(buildParameter.value);
193+
const value = await parameterValue.isChecked();
194+
expect(value).toBe(true);
195+
continue;
196+
}
192197

193-
if (richParameter.type === "bool") {
194-
const parameterField = await parameterLabel.waitForSelector(
195-
`[data-testid='parameter-field-bool'] .MuiRadio-root.Mui-checked${muiDisabled} input`,
196-
);
197-
const value = await parameterField.inputValue();
198-
expect(value).toEqual(buildParameter.value);
199-
} else if (richParameter.options.length > 0) {
200-
const parameterField = await parameterLabel.waitForSelector(
201-
`[data-testid='parameter-field-options'] .MuiRadio-root.Mui-checked${muiDisabled} input`,
202-
);
203-
const value = await parameterField.inputValue();
204-
expect(value).toEqual(buildParameter.value);
205-
} else if (richParameter.type === "list(string)") {
206-
throw new Error("not implemented yet"); // FIXME
207-
} else {
208-
// text or number
209-
const parameterField = await parameterLabel.waitForSelector(
210-
`[data-testid='parameter-field-text'] input${muiDisabled}`,
211-
);
212-
const value = await parameterField.inputValue();
213-
expect(value).toEqual(buildParameter.value);
198+
switch (richParameter.type) {
199+
case "bool":
200+
{
201+
const parameterField = parameterLabel.locator("input");
202+
const value = await parameterField.isChecked();
203+
expect(value.toString()).toEqual(buildParameter.value);
204+
}
205+
break;
206+
case "string":
207+
case "number":
208+
{
209+
const parameterField = parameterLabel.locator("input");
210+
const value = await parameterField.inputValue();
211+
expect(value).toEqual(buildParameter.value);
212+
}
213+
break;
214+
default:
215+
// Some types like `list(string)` are not tested
216+
throw new Error("not implemented yet");
214217
}
215218
}
216219
};
@@ -373,25 +376,22 @@ export const stopWorkspace = async (page: Page, workspaceName: string) => {
373376
});
374377
};
375378

376-
export const buildWorkspaceWithParameters = async (
379+
export const startWorkspaceWithEphemeralParameters = async (
377380
page: Page,
378381
workspaceName: string,
379382
richParameters: RichParameter[] = [],
380383
buildParameters: WorkspaceBuildParameter[] = [],
381-
confirm = false,
382384
) => {
383385
const user = currentUser(page);
384386
await page.goto(`/@${user.username}/${workspaceName}`, {
385387
waitUntil: "domcontentloaded",
386388
});
387389

388-
await page.getByTestId("build-parameters-button").click();
390+
await page.getByTestId("workspace-start").click();
391+
await page.getByTestId("workspace-parameters").click();
389392

390393
await fillParameters(page, richParameters, buildParameters);
391-
await page.getByTestId("build-parameters-submit").click();
392-
if (confirm) {
393-
await page.getByTestId("confirm-button").click();
394-
}
394+
await page.getByRole("button", { name: "Update and restart" }).click();
395395

396396
await page.waitForSelector("text=Workspace status: Running", {
397397
state: "visible",
@@ -547,6 +547,9 @@ interface EchoProvisionerResponses {
547547
plan?: RecursivePartial<Response>[];
548548
// apply occurs when the workspace is built
549549
apply?: RecursivePartial<Response>[];
550+
// extraFiles allows the bundling of terraform files in echo provisioner tars
551+
// in order to support dynamic parameters
552+
extraFiles?: Map<string, string>;
550553
}
551554

552555
const emptyPlan = new TextEncoder().encode("{}");
@@ -595,6 +598,13 @@ const createTemplateVersionTar = async (
595598
}
596599

597600
const tar = new TarWriter();
601+
602+
if (responses.extraFiles) {
603+
for (const [fileName, fileContents] of responses.extraFiles) {
604+
tar.addFile(fileName, fileContents);
605+
}
606+
}
607+
598608
responses.parse.forEach((response, index) => {
599609
response.parse = {
600610
templateVariables: [],
@@ -830,6 +840,50 @@ export const findSessionToken = async (page: Page): Promise<string> => {
830840
export const echoResponsesWithParameters = (
831841
richParameters: RichParameter[],
832842
): EchoProvisionerResponses => {
843+
let tf = `terraform {
844+
required_providers {
845+
coder = {
846+
source = "coder/coder"
847+
}
848+
}
849+
}
850+
`;
851+
852+
for (const parameter of richParameters) {
853+
let options = "";
854+
if (parameter.options) {
855+
for (const option of parameter.options) {
856+
options += `
857+
option {
858+
name = ${JSON.stringify(option.name)}
859+
description = ${JSON.stringify(option.description)}
860+
value = ${JSON.stringify(option.value)}
861+
icon = ${JSON.stringify(option.icon)}
862+
}
863+
`;
864+
}
865+
}
866+
867+
tf += `
868+
data "coder_parameter" "${parameter.name}" {
869+
type = ${JSON.stringify(parameter.type)}
870+
name = ${JSON.stringify(parameter.displayName)}
871+
icon = ${JSON.stringify(parameter.icon)}
872+
description = ${JSON.stringify(parameter.description)}
873+
mutable = ${JSON.stringify(parameter.mutable)}`;
874+
875+
if (!parameter.required) {
876+
tf += `
877+
default = ${JSON.stringify(parameter.defaultValue)}`;
878+
}
879+
880+
tf += `
881+
order = ${JSON.stringify(parameter.order)}
882+
ephemeral = ${JSON.stringify(parameter.ephemeral)}
883+
${options}}
884+
`;
885+
}
886+
833887
return {
834888
parse: [
835889
{
@@ -854,6 +908,7 @@ export const echoResponsesWithParameters = (
854908
},
855909
},
856910
],
911+
extraFiles: new Map([["main.tf", tf]]),
857912
};
858913
};
859914

@@ -903,30 +958,36 @@ const fillParameters = async (
903958
);
904959
}
905960

906-
// Use modern locator approach instead of waitForSelector
907961
const parameterLabel = page.getByTestId(
908-
`parameter-field-${richParameter.name}`,
962+
`parameter-field-${richParameter.displayName}`,
909963
);
910964
await expect(parameterLabel).toBeVisible();
911965

912-
if (richParameter.type === "bool") {
913-
const parameterField = parameterLabel
914-
.getByTestId("parameter-field-bool")
915-
.locator(`.MuiRadio-root input[value='${buildParameter.value}']`);
916-
await parameterField.click();
917-
} else if (richParameter.options.length > 0) {
918-
const parameterField = parameterLabel
919-
.getByTestId("parameter-field-options")
920-
.locator(`.MuiRadio-root input[value='${buildParameter.value}']`);
921-
await parameterField.click();
922-
} else if (richParameter.type === "list(string)") {
923-
throw new Error("not implemented yet"); // FIXME
924-
} else {
925-
// text or number
926-
const parameterField = parameterLabel
927-
.getByTestId("parameter-field-text")
928-
.locator("input");
929-
await parameterField.fill(buildParameter.value);
966+
if (richParameter.options.length > 0) {
967+
const parameterValue = parameterLabel.getByRole("button", {
968+
name: buildParameter.value,
969+
});
970+
await parameterValue.click();
971+
continue;
972+
}
973+
974+
switch (richParameter.type) {
975+
case "bool":
976+
{
977+
const parameterField = parameterLabel.locator("button");
978+
await parameterField.click();
979+
}
980+
break;
981+
case "string":
982+
case "number":
983+
{
984+
const parameterField = parameterLabel.locator("input");
985+
await parameterField.fill(buildParameter.value);
986+
}
987+
break;
988+
default:
989+
// Some types like `list(string)` are not tested
990+
throw new Error("not implemented yet");
930991
}
931992
}
932993
};
@@ -1021,27 +1082,13 @@ export const updateWorkspace = async (
10211082
await page.getByTestId("workspace-update-button").click();
10221083
await page.getByTestId("confirm-button").click();
10231084

1024-
await page.waitForSelector('[data-testid="dialog"]', { state: "visible" });
1085+
await page
1086+
.getByRole("button", { name: /go to workspace parameters/i })
1087+
.click();
10251088

10261089
await fillParameters(page, richParameters, buildParameters);
1027-
await page.getByRole("button", { name: /update parameters/i }).click();
10281090

1029-
// Wait for the update button to detach.
1030-
await page.waitForSelector(
1031-
"button[data-testid='workspace-update-button']:enabled",
1032-
{ state: "detached" },
1033-
);
1034-
// Wait for the workspace to be running again.
1035-
await page.waitForSelector("text=Workspace status: Running", {
1036-
state: "visible",
1037-
});
1038-
// Wait for the stop button to be enabled again
1039-
await page.waitForSelector(
1040-
"button[data-testid='workspace-stop-button']:enabled",
1041-
{
1042-
state: "visible",
1043-
},
1044-
);
1091+
await page.getByRole("button", { name: /update and restart/i }).click();
10451092
};
10461093

10471094
export const updateWorkspaceParameters = async (
@@ -1056,7 +1103,7 @@ export const updateWorkspaceParameters = async (
10561103
});
10571104

10581105
await fillParameters(page, richParameters, buildParameters);
1059-
await page.getByRole("button", { name: /submit and restart/i }).click();
1106+
await page.getByRole("button", { name: /update and restart/i }).click();
10601107

10611108
await page.waitForSelector("text=Workspace status: Running", {
10621109
state: "visible",
@@ -1209,48 +1256,3 @@ export async function addUserToOrganization(
12091256
}
12101257
await page.mouse.click(10, 10); // close the popover by clicking outside of it
12111258
}
1212-
1213-
/**
1214-
* disableDynamicParameters navigates to the template settings page and disables
1215-
* dynamic parameters by unchecking the "Enable dynamic parameters" checkbox.
1216-
*/
1217-
export const disableDynamicParameters = async (
1218-
page: Page,
1219-
templateName: string,
1220-
orgName = defaultOrganizationName,
1221-
) => {
1222-
await page.goto(`/templates/${orgName}/${templateName}/settings`, {
1223-
waitUntil: "domcontentloaded",
1224-
});
1225-
1226-
await page.waitForSelector("form", { state: "visible" });
1227-
1228-
// Find and uncheck the "Enable dynamic parameters" checkbox
1229-
const dynamicParamsCheckbox = page.getByRole("checkbox", {
1230-
name: /Enable dynamic parameters for workspace creation/,
1231-
});
1232-
1233-
await dynamicParamsCheckbox.waitFor({ state: "visible" });
1234-
1235-
// If the checkbox is checked, uncheck it
1236-
if (await dynamicParamsCheckbox.isChecked()) {
1237-
await dynamicParamsCheckbox.click();
1238-
}
1239-
1240-
// Save the changes
1241-
const saveButton = page.getByRole("button", { name: /save/i });
1242-
await saveButton.waitFor({ state: "visible" });
1243-
await saveButton.click();
1244-
1245-
// Wait for the success message or page to update
1246-
await page
1247-
.locator("[role='alert']:has-text('Template updated successfully')")
1248-
.first()
1249-
.waitFor({
1250-
state: "visible",
1251-
timeout: 15000,
1252-
});
1253-
1254-
// Additional wait to ensure the changes are persisted
1255-
await page.waitForTimeout(500);
1256-
};

site/e2e/parameters.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const thirdParameter: RichParameter = {
5353
...emptyParameter,
5454

5555
name: "third_parameter",
56+
displayName: "Third parameter",
5657
type: "string",
5758
description: "This is third parameter.",
5859
defaultValue: "",
@@ -65,6 +66,7 @@ export const fourthParameter: RichParameter = {
6566
...emptyParameter,
6667

6768
name: "fourth_parameter",
69+
displayName: "Fourth parameter",
6870
type: "bool",
6971
description: "This is fourth parameter.",
7072
defaultValue: "true",

site/e2e/tests/workspaces/autoCreateWorkspace.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ test.beforeAll(async ({ browser }) => {
1919
await login(page, users.templateAdmin);
2020

2121
const richParameters: RichParameter[] = [
22-
{ ...emptyParameter, name: "repo", type: "string" },
22+
{ ...emptyParameter, name: "repo", displayName: "Repo", type: "string" },
2323
];
2424
template = await createTemplate(
2525
page,

0 commit comments

Comments
 (0)