mirror of https://github.com/coder/coder.git
test(site): add e2e tests for experiments (#12940)
This commit is contained in:
parent
b163bc7f01
commit
dcf1d3a9ae
|
@ -37,3 +37,7 @@ export const requireEnterpriseTests = Boolean(
|
||||||
process.env.CODER_E2E_REQUIRE_ENTERPRISE_TESTS,
|
process.env.CODER_E2E_REQUIRE_ENTERPRISE_TESTS,
|
||||||
);
|
);
|
||||||
export const enterpriseLicense = process.env.CODER_E2E_ENTERPRISE_LICENSE ?? "";
|
export const enterpriseLicense = process.env.CODER_E2E_ENTERPRISE_LICENSE ?? "";
|
||||||
|
|
||||||
|
// Fake experiments to verify that site presents them as enabled.
|
||||||
|
export const e2eFakeExperiment1 = "e2e-fake-experiment-1";
|
||||||
|
export const e2eFakeExperiment2 = "e2e-fake-experiment-2";
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
import { defineConfig } from "@playwright/test";
|
import { defineConfig } from "@playwright/test";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import { coderMain, coderPort, coderdPProfPort, gitAuth } from "./constants";
|
import {
|
||||||
|
coderMain,
|
||||||
|
coderPort,
|
||||||
|
coderdPProfPort,
|
||||||
|
e2eFakeExperiment1,
|
||||||
|
e2eFakeExperiment2,
|
||||||
|
gitAuth,
|
||||||
|
} from "./constants";
|
||||||
|
|
||||||
export const wsEndpoint = process.env.CODER_E2E_WS_ENDPOINT;
|
export const wsEndpoint = process.env.CODER_E2E_WS_ENDPOINT;
|
||||||
|
|
||||||
|
@ -22,7 +29,7 @@ export default defineConfig({
|
||||||
testMatch: /.*\.spec\.ts/,
|
testMatch: /.*\.spec\.ts/,
|
||||||
dependencies: ["testsSetup"],
|
dependencies: ["testsSetup"],
|
||||||
use: { storageState },
|
use: { storageState },
|
||||||
timeout: 20_000,
|
timeout: 50_000,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
reporter: [["./reporter.ts"]],
|
reporter: [["./reporter.ts"]],
|
||||||
|
@ -60,6 +67,8 @@ export default defineConfig({
|
||||||
.join(" "),
|
.join(" "),
|
||||||
env: {
|
env: {
|
||||||
...process.env,
|
...process.env,
|
||||||
|
// Otherwise, the runner fails on Mac with: could not determine kind of name for C.uuid_string_t
|
||||||
|
CGO_ENABLED: "0",
|
||||||
|
|
||||||
// This is the test provider for git auth with devices!
|
// This is the test provider for git auth with devices!
|
||||||
CODER_GITAUTH_0_ID: gitAuth.deviceProvider,
|
CODER_GITAUTH_0_ID: gitAuth.deviceProvider,
|
||||||
|
@ -101,6 +110,7 @@ export default defineConfig({
|
||||||
gitAuth.validatePath,
|
gitAuth.validatePath,
|
||||||
),
|
),
|
||||||
CODER_PPROF_ADDRESS: "127.0.0.1:" + coderdPProfPort,
|
CODER_PPROF_ADDRESS: "127.0.0.1:" + coderdPProfPort,
|
||||||
|
CODER_EXPERIMENTS: e2eFakeExperiment1 + "," + e2eFakeExperiment2,
|
||||||
},
|
},
|
||||||
reuseExistingServer: false,
|
reuseExistingServer: false,
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { expect, test } from "@playwright/test";
|
||||||
|
import * as API from "api/api";
|
||||||
|
import { setupApiCalls } from "../../api";
|
||||||
|
import { e2eFakeExperiment1, e2eFakeExperiment2 } from "../../constants";
|
||||||
|
|
||||||
|
test("experiments", async ({ page }) => {
|
||||||
|
await setupApiCalls(page);
|
||||||
|
|
||||||
|
// Load experiments from backend API
|
||||||
|
const availableExperiments = await API.getAvailableExperiments();
|
||||||
|
|
||||||
|
// Verify if the site lists the same experiments
|
||||||
|
await page.goto("/deployment/general", { waitUntil: "networkidle" });
|
||||||
|
|
||||||
|
const experimentsLocator = page.locator(
|
||||||
|
"div.options-table tr.option-experiments ul.option-array",
|
||||||
|
);
|
||||||
|
await expect(experimentsLocator).toBeVisible();
|
||||||
|
|
||||||
|
// Firstly, check if all enabled experiments are listed
|
||||||
|
expect(
|
||||||
|
experimentsLocator.locator(
|
||||||
|
`li.option-array-item-${e2eFakeExperiment1}.option-enabled`,
|
||||||
|
),
|
||||||
|
).toBeVisible;
|
||||||
|
expect(
|
||||||
|
experimentsLocator.locator(
|
||||||
|
`li.option-array-item-${e2eFakeExperiment2}.option-enabled`,
|
||||||
|
),
|
||||||
|
).toBeVisible;
|
||||||
|
|
||||||
|
// Secondly, check if available experiments are listed
|
||||||
|
for (const experiment of availableExperiments.safe) {
|
||||||
|
const experimentLocator = experimentsLocator.locator(
|
||||||
|
`li.option-array-item-${experiment}`,
|
||||||
|
);
|
||||||
|
await expect(experimentLocator).toBeVisible();
|
||||||
|
}
|
||||||
|
});
|
|
@ -51,7 +51,7 @@ export const OptionValue: FC<OptionValueProps> = (props) => {
|
||||||
|
|
||||||
if (typeof value === "object" && !Array.isArray(value)) {
|
if (typeof value === "object" && !Array.isArray(value)) {
|
||||||
return (
|
return (
|
||||||
<ul css={{ listStyle: "none" }}>
|
<ul css={{ listStyle: "none" }} className="option-array">
|
||||||
{Object.entries(value)
|
{Object.entries(value)
|
||||||
.sort((a, b) => a[0].localeCompare(b[0]))
|
.sort((a, b) => a[0].localeCompare(b[0]))
|
||||||
.map(([option, isEnabled]) => (
|
.map(([option, isEnabled]) => (
|
||||||
|
@ -64,6 +64,9 @@ export const OptionValue: FC<OptionValueProps> = (props) => {
|
||||||
color: theme.palette.text.disabled,
|
color: theme.palette.text.disabled,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
className={`option-array-item-${option} ${
|
||||||
|
isEnabled ? "option-enabled" : "option-disabled"
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
css={{
|
css={{
|
||||||
|
|
|
@ -27,7 +27,7 @@ const OptionsTable: FC<OptionsTableProps> = ({ options, additionalValues }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableContainer>
|
<TableContainer className="options-table">
|
||||||
<Table
|
<Table
|
||||||
css={css`
|
css={css`
|
||||||
& td {
|
& td {
|
||||||
|
@ -57,7 +57,7 @@ const OptionsTable: FC<OptionsTableProps> = ({ options, additionalValues }) => {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<TableRow key={option.flag}>
|
<TableRow key={option.flag} className={"option-" + option.flag}>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<OptionName>{option.name}</OptionName>
|
<OptionName>{option.name}</OptionName>
|
||||||
<OptionDescription>{option.description}</OptionDescription>
|
<OptionDescription>{option.description}</OptionDescription>
|
||||||
|
|
Loading…
Reference in New Issue