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,
|
||||
);
|
||||
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 * 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;
|
||||
|
||||
|
@ -22,7 +29,7 @@ export default defineConfig({
|
|||
testMatch: /.*\.spec\.ts/,
|
||||
dependencies: ["testsSetup"],
|
||||
use: { storageState },
|
||||
timeout: 20_000,
|
||||
timeout: 50_000,
|
||||
},
|
||||
],
|
||||
reporter: [["./reporter.ts"]],
|
||||
|
@ -60,6 +67,8 @@ export default defineConfig({
|
|||
.join(" "),
|
||||
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!
|
||||
CODER_GITAUTH_0_ID: gitAuth.deviceProvider,
|
||||
|
@ -101,6 +110,7 @@ export default defineConfig({
|
|||
gitAuth.validatePath,
|
||||
),
|
||||
CODER_PPROF_ADDRESS: "127.0.0.1:" + coderdPProfPort,
|
||||
CODER_EXPERIMENTS: e2eFakeExperiment1 + "," + e2eFakeExperiment2,
|
||||
},
|
||||
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)) {
|
||||
return (
|
||||
<ul css={{ listStyle: "none" }}>
|
||||
<ul css={{ listStyle: "none" }} className="option-array">
|
||||
{Object.entries(value)
|
||||
.sort((a, b) => a[0].localeCompare(b[0]))
|
||||
.map(([option, isEnabled]) => (
|
||||
|
@ -64,6 +64,9 @@ export const OptionValue: FC<OptionValueProps> = (props) => {
|
|||
color: theme.palette.text.disabled,
|
||||
},
|
||||
]}
|
||||
className={`option-array-item-${option} ${
|
||||
isEnabled ? "option-enabled" : "option-disabled"
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
css={{
|
||||
|
|
|
@ -27,7 +27,7 @@ const OptionsTable: FC<OptionsTableProps> = ({ options, additionalValues }) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<TableContainer>
|
||||
<TableContainer className="options-table">
|
||||
<Table
|
||||
css={css`
|
||||
& td {
|
||||
|
@ -57,7 +57,7 @@ const OptionsTable: FC<OptionsTableProps> = ({ options, additionalValues }) => {
|
|||
return null;
|
||||
}
|
||||
return (
|
||||
<TableRow key={option.flag}>
|
||||
<TableRow key={option.flag} className={"option-" + option.flag}>
|
||||
<TableCell>
|
||||
<OptionName>{option.name}</OptionName>
|
||||
<OptionDescription>{option.description}</OptionDescription>
|
||||
|
|
Loading…
Reference in New Issue