Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3d7740b

Browse files
authored
test(site): add e2e tests for workspace proxies (#13009)
1 parent3aa0d73 commit3d7740b

File tree

8 files changed

+164
-5
lines changed

8 files changed

+164
-5
lines changed

‎site/e2e/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const coderPort = process.env.CODER_E2E_PORT
77
?Number(process.env.CODER_E2E_PORT)
88
:3111;
99
exportconstprometheusPort=2114;
10+
exportconstworkspaceProxyPort=3112;
1011

1112
// Use alternate ports in case we're running in a Coder Workspace.
1213
exportconstagentPProfPort=6061;

‎site/e2e/helpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ export const stopAgent = async (cp: ChildProcess, goRun: boolean = true) => {
391391
awaitwaitUntilUrlIsNotResponding("http://localhost:"+prometheusPort);
392392
};
393393

394-
constwaitUntilUrlIsNotResponding=async(url:string)=>{
394+
exportconstwaitUntilUrlIsNotResponding=async(url:string)=>{
395395
constmaxRetries=30;
396396
constretryIntervalMs=1000;
397397
letretries=0;

‎site/e2e/proxy.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import{spawn,typeChildProcess,exec}from"child_process";
2+
import{coderMain,coderPort,workspaceProxyPort}from"./constants";
3+
import{waitUntilUrlIsNotResponding}from"./helpers";
4+
5+
exportconststartWorkspaceProxy=async(
6+
token:string,
7+
):Promise<ChildProcess>=>{
8+
constcp=spawn("go",["run",coderMain,"wsproxy","server"],{
9+
env:{
10+
...process.env,
11+
CODER_PRIMARY_ACCESS_URL:`http://127.0.0.1:${coderPort}`,
12+
CODER_PROXY_SESSION_TOKEN:token,
13+
CODER_HTTP_ADDRESS:`localhost:${workspaceProxyPort}`,
14+
},
15+
});
16+
cp.stdout.on("data",(data:Buffer)=>{
17+
// eslint-disable-next-line no-console -- Log wsproxy activity
18+
console.log(
19+
`[wsproxy] [stdout] [onData]${data.toString().replace(/\n$/g,"")}`,
20+
);
21+
});
22+
cp.stderr.on("data",(data:Buffer)=>{
23+
// eslint-disable-next-line no-console -- Log wsproxy activity
24+
console.log(
25+
`[wsproxy] [stderr] [onData]${data.toString().replace(/\n$/g,"")}`,
26+
);
27+
});
28+
returncp;
29+
};
30+
31+
exportconststopWorkspaceProxy=async(
32+
cp:ChildProcess,
33+
goRun:boolean=true,
34+
)=>{
35+
exec(goRun ?`pkill -P${cp.pid}` :`kill${cp.pid}`,(error)=>{
36+
if(error){
37+
thrownewError(`exec error:${JSON.stringify(error)}`);
38+
}
39+
});
40+
awaitwaitUntilUrlIsNotResponding(`http://127.0.0.1:${workspaceProxyPort}`);
41+
};

‎site/e2e/tests/deployment/appearance.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ test("set application logo", async ({ page }) => {
5252
awaitincognitoPage.goto("/",{waitUntil:"domcontentloaded"});
5353

5454
// Verify banner
55-
constlogo=incognitoPage.locator("img");
55+
constlogo=incognitoPage.locator("img.application-logo");
5656
awaitexpect(logo).toHaveAttribute("src",imageLink);
5757

5858
// Shut down browser
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import{test,expect,typePage}from"@playwright/test";
2+
import{createWorkspaceProxy}from"api/api";
3+
import{setupApiCalls}from"../../api";
4+
import{coderPort,workspaceProxyPort}from"../../constants";
5+
import{randomName,requiresEnterpriseLicense}from"../../helpers";
6+
import{startWorkspaceProxy,stopWorkspaceProxy}from"../../proxy";
7+
8+
test("default proxy is online",async({ page})=>{
9+
requiresEnterpriseLicense();
10+
awaitsetupApiCalls(page);
11+
12+
awaitpage.goto("/deployment/workspace-proxies",{
13+
waitUntil:"domcontentloaded",
14+
});
15+
16+
// Verify if the default proxy is healthy
17+
constworkspaceProxyPrimary=page.locator(
18+
`table.MuiTable-root tr[data-testid="primary"]`,
19+
);
20+
21+
constworkspaceProxyName=workspaceProxyPrimary.locator("td.name span");
22+
constworkspaceProxyURL=workspaceProxyPrimary.locator("td.url");
23+
constworkspaceProxyStatus=workspaceProxyPrimary.locator("td.status span");
24+
25+
awaitexpect(workspaceProxyName).toHaveText("Default");
26+
awaitexpect(workspaceProxyURL).toHaveText("http://localhost:"+coderPort);
27+
awaitexpect(workspaceProxyStatus).toHaveText("Healthy");
28+
});
29+
30+
test("custom proxy is online",async({ page})=>{
31+
requiresEnterpriseLicense();
32+
awaitsetupApiCalls(page);
33+
34+
constproxyName=randomName();
35+
36+
// Register workspace proxy
37+
constproxyResponse=awaitcreateWorkspaceProxy({
38+
name:proxyName,
39+
display_name:"",
40+
icon:"/emojis/1f1e7-1f1f7.png",
41+
});
42+
expect(proxyResponse.proxy_token).toBeDefined();
43+
44+
// Start "wsproxy server"
45+
constproxyServer=awaitstartWorkspaceProxy(proxyResponse.proxy_token);
46+
awaitwaitUntilWorkspaceProxyIsHealthy(page,proxyName);
47+
48+
// Verify if custom proxy is healthy
49+
awaitpage.goto("/deployment/workspace-proxies",{
50+
waitUntil:"domcontentloaded",
51+
});
52+
53+
constworkspaceProxy=page.locator(`table.MuiTable-root tr`,{
54+
hasText:proxyName,
55+
});
56+
57+
constworkspaceProxyName=workspaceProxy.locator("td.name span");
58+
constworkspaceProxyURL=workspaceProxy.locator("td.url");
59+
constworkspaceProxyStatus=workspaceProxy.locator("td.status span");
60+
61+
awaitexpect(workspaceProxyName).toHaveText(proxyName);
62+
awaitexpect(workspaceProxyURL).toHaveText(
63+
`http://127.0.0.1:${workspaceProxyPort}`,
64+
);
65+
awaitexpect(workspaceProxyStatus).toHaveText("Healthy");
66+
67+
// Tear down the proxy
68+
awaitstopWorkspaceProxy(proxyServer);
69+
});
70+
71+
constwaitUntilWorkspaceProxyIsHealthy=async(
72+
page:Page,
73+
proxyName:string,
74+
)=>{
75+
awaitpage.goto("/deployment/workspace-proxies",{
76+
waitUntil:"domcontentloaded",
77+
});
78+
79+
constmaxRetries=30;
80+
constretryIntervalMs=1000;
81+
letretries=0;
82+
while(retries<maxRetries){
83+
awaitpage.reload();
84+
85+
constworkspaceProxy=page.locator(`table.MuiTable-root tr`,{
86+
hasText:proxyName,
87+
});
88+
constworkspaceProxyStatus=workspaceProxy.locator("td.status span");
89+
90+
try{
91+
awaitexpect(workspaceProxyStatus).toHaveText("Healthy",{
92+
timeout:1_000,
93+
});
94+
return;// healthy!
95+
}catch{
96+
retries++;
97+
awaitnewPromise((resolve)=>setTimeout(resolve,retryIntervalMs));
98+
}
99+
}
100+
thrownewError(
101+
`Workspace proxy "${proxyName}" is unhealthy after${
102+
maxRetries*retryIntervalMs
103+
}ms`,
104+
);
105+
};

‎site/src/api/api.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,13 @@ export const getWorkspaceProxies = async (): Promise<
12701270
returnresponse.data;
12711271
};
12721272

1273+
exportconstcreateWorkspaceProxy=async(
1274+
b:TypesGen.CreateWorkspaceProxyRequest,
1275+
):Promise<TypesGen.UpdateWorkspaceProxyResponse>=>{
1276+
constresponse=awaitaxios.post(`/api/v2/workspaceproxies`,b);
1277+
returnresponse.data;
1278+
};
1279+
12731280
exportconstgetAppearance=async():Promise<TypesGen.AppearanceConfig>=>{
12741281
try{
12751282
constresponse=awaitaxios.get(`/api/v2/appearance`);

‎site/src/pages/LoginPage/LoginPageView.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const LoginPageView: FC<LoginPageViewProps> = ({
4141
css={{
4242
maxWidth:"200px",
4343
}}
44+
className="application-logo"
4445
/>
4546
) :(
4647
<CoderIconfill="white"opacity={1}css={styles.icon}/>

‎site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyRow.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const ProxyRow: FC<ProxyRowProps> = ({ proxy, latency }) => {
4040
return(
4141
<>
4242
<TableRowkey={proxy.name}data-testid={proxy.name}>
43-
<TableCell>
43+
<TableCellclassName="name">
4444
<AvatarData
4545
title={
4646
proxy.display_name&&proxy.display_name.length>0
@@ -60,8 +60,12 @@ export const ProxyRow: FC<ProxyRowProps> = ({ proxy, latency }) => {
6060
/>
6161
</TableCell>
6262

63-
<TableCellcss={{fontSize:14}}>{proxy.path_app_url}</TableCell>
64-
<TableCellcss={{fontSize:14}}>{statusBadge}</TableCell>
63+
<TableCellcss={{fontSize:14}}className="url">
64+
{proxy.path_app_url}
65+
</TableCell>
66+
<TableCellcss={{fontSize:14}}className="status">
67+
{statusBadge}
68+
</TableCell>
6569
<TableCell
6670
css={{
6771
fontSize:14,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp